An Introduction to Hasura and GraphQL
You might have heard about Hasura, the new technology that lets you quickly create GraphQL APIs to access data in your databases. Here's a quick tutorial that will help you understand why technologies like GraphQL and Hasura are so important for API development. For an example of where you might use Hasura, imagine we're building an app to store comments in a Postgres database. In our application, we need to be able to do two things: But how exactly do we communicate with the database from a frontend application? That's where Hasura comes into play. It will generate GraphQL APIs from a database. That way, from the frontend, we will communicate with Hasura through GraphQL, and beneath, Hasura will handle accessing the database. GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL comes with important advantages: GraphQL has emerged as an alternative to REST APIs for client-server communication requirements. Which one you choose depends much on your objectives and the specific needs of your app. A GraphQL server exposes one endpoint and accepts POST requests . The body of the request is a stringified JSON object that contains a query , along with variables . Here's an example: Here, query is a request written in GraphQL language, and variables stores values that we can use in the request. But let's take it bit by bit. The core part of a GraphQL server is a GraphQL schema. It describes the data available to the client applications. For example, for a GraphQL server created on top of a database with single table users , the schema could look like this: The schema tells us what types we can expect for particular fields. Hence we know that the returned name , for example, will always be a String . To get data from a GraphQL service, we use a query . We construct it by specifying the root type, e.g. User , and all the fields we want from the type. For example, the server exposes fields id , name , and age for the User type. But maybe we don't need all of them? One of the core concepts of GraphQL is the "take what you want" approach. We can ask for exactly what we need. When it doesn't have any parameters, the query doesn't need a name: Or we can skip query . This still is valid GraphQL syntax: This is a request that the client application would send: We can also pass variables. Let's say we want to fetch a particular user based on the user id : For modifying data, GraphQL provides us mutations . These let us update one or more objects. Take a look at the following example: We pass dynamic values for a new user's name and age , and we also return the id of a newly created user. What does it mean? It means that mutations can not only be used to modify underlying resources, but we also get results back. Sometimes, your application needs real-time data. For example, you're building a chat application and need to display up-to-date message updates. With GraphQL, we can subscribe to real-time data from a server, using subscriptions . They have the same format as queries, with the only difference being a subscription keyword instead of query . The subscription API is exposed over WebSockets, so we need to hit a WebSocket URL from a client. It means that instead of sending requests to the server on https://your-server.app/graphql , we use the WebSocket protocol: ws://your-server.app/graphql . As we mentioned before, sending GraphQL requests is no more than sending POST requests over HTTP to an endpoint. For this reason, on the client, we can use built-in browser APIs. However, the GraphQL ecosystem now has multiple clients, including: Clients like these provide cache support, subscriptions support, and much more. When building bigger apps, you'll want to use a GraphQL client. GraphQL is a very convenient way to work with JSON data. It can be used with any language or framework. It's not tied to any specific database, and on top of that, it has an excellent ecosystem and a huge community. We gain a lot of flexibility by using GraphQL. Instead of waiting for a new endpoint whenever we need to fetch a different set of data, we can handle it independently by writing an adequate query based on our specification. We also don't have to send multiple endpoints to fetch the information - we can handle it in one GraphQL query. Congratulations - you just learned the basics of GraphQL. It's a lot of new knowledge, but don't worry - we'll play a bit with queries and mutations in follow up lessons on the topics of GraphQL as well as Hasura.