Elm-postgrest: A Remote Data Request API in Elm

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

Here’s a link to the blog post: A Remote Data Request API in Elm


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
resource schema
attributes
relationships
cardinality
Abstraction Barrier
Transfer Protocol Interchange Format
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.

Thanks for your time everyone.

4 Likes

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.

In short, Yes.

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!

1 Like

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.

Ah, that totally makes sense!

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. :smile:

1 Like

GREAT work John! PostgREST and Elm seem like a wonderful combination because they’re both so far in the “work smarter, not harder” direction.

1 Like

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?

1 Like

@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.

1 Like