Hey everyone. I’ve been working on an elm client for the backend technology PostgREST. Even if you don’t care about PostgREST, I think that you’ll find the post interesting. The post talks about both:
the core abstractions found in the elm-postgrest package and how those abstractions may be relevant to similar packages
In the beginning of the post, I spend a bit of time going over my understanding of the design space of Remote Data Request APIs in Elm. I hope this overview is helpful to anyone designing APIs in this space. Here’s a diagram from the post to preview some of the ideas:
Request Builder
Schema Description
CRUD requests selections conditions order limit and offset pagination
HTTP: headers body methods url: query and fragment status codes
json edn xml transit protobuf
In addition to the post, I forked Richard Feldman’s elm-spa-example to exemplify the use of elm-postgrest. Here’s a link to that: john-kelly/elm-postgrest-spa-example. In that repo, I wrote a custom PostgREST backend and re-implemented Richard’s Request module with john-kelly/elm-postgrest.
I’m still actively developing john-kelly/elm-postgrest, so if you’re curious, checkout out the dev branch.
Good to see this making progress. I remember you posted an early prototype maybe more than a year ago on elm-discuss.
Could a graphql API wrapper be put around Postgrest? The attraction of that would be that the database choice would be less baked into the stack that way; you could keep the same API and front-end but move to a different database.
Yes, you could implement GraphQL on top of PostgREST. I’ve never done so, but there’s a prominent member in the PostgREST community who has done so. Here’s a link to his project: https://subzero.cloud/
Additionally, you could just write a web server that adheres to the PostgREST specification. This would require a bit of work, but it’s certainly doable. At that point, you could choose any backend stack.
The counterpoint to this is that I’ve seen many libraries in many languages over the years aim for this, and so far I’ve never seen one succeed. I’ve learned the hard way that switching databases is a serious undertaking, no matter what the library does!
Having learned this, I eventually came to the conclusion that libraries contorting themselves to make it seem like switching won’t be hard primarily serves to hold the libraries back from being really excellent at supporting one database.
I think it’s best to constrain your design goal to being the best API you can for supporting one database, and that’s it!
Ok, this is true. Changing DB on a mature project would be very hard.
The reason I like to be able to switch database is for building prototypes. So I’ll start with a sketch of a data model, and just store it as json in a key-value store. Hack some code around that, and as things begin to mature I can decide, is it a very relational model that would suit a SQL db, or can it live in a noSQL db?
Prototyping and getting up and running quickly is also the reason I would use something like PostgREST, but I might not stick with it beyond that. Good for CRUD but I usually want more business logic on the server side.
Although to be fair, Elm’s compiler generally makes it pretty easy to refactor from one library to another on a small project, as long as they’re basically serving the same purpose.
Interesting API approach, I look forward to exploring this when I get the opportunity.
I stumbled a bit over the typo error message, the part with PG.field .titl. This seems to be the immediate mismatch between the type signature and the implementation. I imagine that if the the type signature of articleSelection were removed, we’d see an error when checking the types in PG.readAll articleSchema articleSelection, because the two attributes types differ?
@rob If I’m understanding you fully – you are correct. Now that I’m taking a second look, I agree that the example doesn’t directly support the claim made in the post (but that’s not to say the point doesn’t still stand). The error will occur
Despite this confusing example, the point made in the article regarding type safety still stands:
If the Schema is valid, our Request will be valid
If the Article schema is correct, building the request with the incorrect selection (PG.field .titl) will yield a compiler error.