Setting the scene
For this three-part series, I will be creating a very simple example CMS platform for writing and viewing blog posts using a GraphQL server and a VueJS client. As such, a focus has been made on creating a platform that shows the capabilities of GraphQL and not one that represents a production-ready CMS.
The CMS platform will conveniently contain three parts, one part for each of the three posts in this series.
- An Apollo GraphQL server used to wrap the Auth0 Management API with GraphQL so that the Hasura GraphQL Server can link to it.
- A Hasura GraphQL server used to store the blog posts and provided a CRUD interface in GraphQL between the client and the PostgreSQL backend.
- A VueJS client-side application to present a simple user interface in the web browser to the client so that a blog post can be created, modified and viewed as well as providing a way to authenticate and authorise users.
I have chosen to use both an Apollo GraphQL server and a Hasura GraphQL server here to show how it is possible to connect two different servers and merge their schemas so from a server perspective they are two physically different systems. However, as far as the client is concerned, it is one single endpoint. By using a single endpoint, it has the advantage of fewer requests being made from the client improving performance (one request getting all the required information, instead of multiple requests getting little bits and pieces of the bigger picture). GraphQL will also only ever return what is queried rather than the full available payload (like standard HTTP APIs).
For the curious
All the code for this project is available here and the entire project for those who want to skip ahead and get everything running is available here
To get the project running you will need an Auth0 account with the Management API setup and docker installed and ready to go. The project has also been generated using Yarn2 and Node 14
Creating an Apollo GraphQL Server
For this CMS platform, we want to retrieve information about the user and any relevant details, such as the posts that they have made. We also want the application to be secured behind Auth0 so that only registered users can create new posts. By connecting these two features, we can see that Auth0 is storing our user information, and later, we will be making a Hasura GraphQL instance to keep the blog posts. Still, there is an issue, Hasura is GraphQL, and the Auth0 management API to get user account information is RESTful. As a solution to this, we will be creating an Apollo GraphQL server to wrap the Auth0 API behind and then merge the Apollo and Hasura schemas so that the client application can access this data in one go.
For this example, we will only create a fundamental GraphQL API that exposes user information such as their name, profile picture, email and a unique user id that can be used later for querying for their blog posts.
The Schema
Step one in creating the Apollo GraphQL server is defining its schema, what can it do. A simple schema defined in TypeScript would look something like this;
In this example, we are defining a custom schema type called DateTime which is internally mapped by Apollo to a JavaScript date-time object, however, it needs to be explicitly defined here so that the server knows that it is allowed to use it.
There is also a User type which describes what a user interface contains and finally there is a Query type which explains what information can be queried on this server. In this case, two queries can be made, one to request a single user by their id and another one to search for users by their name.
Resolving Requests
The next step is to resolve the requests that have been made and return some information. In the following example, we are doing this by mapping the GraphQL queries to TypeScript functions.
The first interface (Context) contains some details of data that is available on each request. The following interface is the TypeScript type for the resolvers. Finally, the exported constant variable is the resolvers used to map the query to a function.
Bringing it all together
The final step is to bring the type definitions and the resolvers together and to launch the Apollo server so that we can start querying it. That is where this final TypeScript section comes in. Its job is to establish an express server with the Apollo middleware attached.
Checking it works
Finally, once it is all running, we can test the schema using the GraphiQL IDE built into the Apollo GraphQL server that is available from the GraphQL endpoint, for example in this project it is available from http://localhost:5000/graphql. The following images represent the three different queries that the GraphQL API expose. The first one represents retrieving all users who are registered with the application. The second one queries for all users who are registered with the system and match the name filter. The final one gets a single registered user by their unique id.
Conclusion
In this blog post, I covered how to create an Apollo GraphQL server to expose the Auth0 Management API to query user information. In the next post, I will cover how to create a Hasura GraphQL instance and merge the two schemas, so it is possible to query both the user information and the blog post in one request.