Why you're reading this
- dev.to has a REST API that is probably becoming public in the near future
- GraphQL is a solid and proven technology now and is one of those that many people here want to get comfortable with in 2019
- PostgreSQL (which dev.to uses) is my favorite relational database
I decided to try Hasura which promises to let people build a GraphQL API that speaks directly to the PostgreSQL database.
I didn't expect to be done with my demo 15 minutes later writing only the GraphQL queries themselves and one SQL statement. No other code at all.
Let me backtrack a bit and explain what Hasura is.
Hasura
The tool is a GraphQL engine/server written in Haskell and JavaScript. It sits between a client application (API consumer for example) and the database (PostgreSQL).
The client sends the GraphQL query, the server gets it, parses it, validates it, transforms it to a highly optimized SQL query, fetches the data in JSON format (PostgreSQL allows you to export data in JSON without going back to the web app, one of its best recent features if you ask me) and sends it back to the client.
If you want to read more about the architecture you can read Hasura's article: Architecture of a high performance GraphQL to SQL engine.
So, after reading only that article out of curiosity, I decided to give it a go trying to read as little documentation as possible.
It went well.
Setting up the server
The setup is quite straightforward. I installed Docker for Mac, downloaded a script, ran its contents and waited:
docker run -p 8080:8080 -e HASURA_GRAPHQL_DATABASE_URL=postgres://username:password@host:port/db -e HASURA_GRAPHQL_ENABLE_CONSOLE=true hasura/graphql-engine:v1.0.0-alpha34
After that, I opened the console with a browser and this appeared:
Preparing the schema
Clicking on Data
reveals the list of tables contained in the database chosen. I instructed Hasura to expose the articles
, comments
and users
table, clicked around a bit in the UI to create relationships between them and the result was the following:
The only thing I had to setup manually is articles_comments
which doesn't exist in the default dev.to database.
Hasura doesn't support polymorphic associations as they are created by Ruby on Rails. The solution, found searching the issue tracker, was to create a simple view:
create view articles_comments as select * from comments where commentable_type = 'Article';
Querying the data
With the schema and the relationship setup I went on two write a few GraphQL queries with and without nested data to see if everything worked.
the last 10 users with their last 3 comments
the most popular article with the most popular comment and the name of its author
This last query is one of those reasons why GraphQL can be advantageous over REST. REST(ish) APIs tend to be kind of a drag when you need to ask for nested or related data. Think about it, we're asking the web server to retrieve the post with the most reactions, then fetch the comment with the most likes and its author.
In a classic REST(ish) API you would invoke the HTTP web server three times:
- give me the article sorted by popularity
- give me the comment sorted by popularity, here I give you the id of the article
- give me the user, here I give you the comment id
You might get to one HTTP call in some REST APIs but it's a possibility, not the default. GraphQL in this case lowers the barrier:
- any GraphQL client can talk to your server without speaking your own version of REST
- the roundtrip is only one
- the API is self documenting, which is a huge advantage during the exploration phase
Clicking on the "Analyze" button in the Hasura interface yields the SQL and the execution plan:
I stopped at this point and wrote this article. Hasura though supports lots of other features:
- mutations
- subscriptions (basically realtime notifications of data changes in the DB, which you can hook up to a UI)
- auth and row level access control (you can decide what to expose and what not to)
- schema stitching (external GraphQL APIs that need to be exposed through yours transparently)
- webhooks on events
- migrations
Hasura also deploys on Heroku, Digital Ocean and Kubernetes.
I only tried it a few minutes so I can't say anything else but it's surely an interesting tool for people who want to build a GraphQL API on top of an existing database.
Top comments (3)
Super neat
Yes, I'll try to test the other features in the following weeks. As every tool it does have a cost but it seems better than rolling a GraphQL API from scratch inside the web app.
Pretty cool.
When I first read about Hasura I had the impression it was a GraphQL library that lets me write resolvers client-side.