As I’ve grown quite fond of GraphQL API’s in the past months, I wanted to take this opportunity to document how to get a GraphQL API up and running in Node.js using TypeScript, TypeGraphQL, Express and Apollo.
What is GraphQL?
GraphQL is query language for API’s which simplifies making requests and makes them more data efficient as compared to the more traditional REST API’s. GraphQL provides static typing for requests and allows users to select exactly which fields they need. It also allows for querying data of different types in the same request which would typically require multiple requests with a REST API. To add on, one of the most convenient features of GraphQL API’s is that all requests are made the same endpoint. To illustrate the benefits of GraphQL API’s over REST API’s, I will provide an example of the same use-case using both GraphQL and REST.
The Example
Let’s say that we are looking to query user data as well as game data for a chess game on the same page. However, we only need the user’s first name and last name and only the current status of the game.
REST API
For the user data, we’d make a GET request with a query parameter for the username. For example, http://localhost:8080/user?username=ammar123
This would return a JSON object containing the entire user object:
You would then select the first and last name to render in the webpage.
For the game data, we’d make another GET request with a query parameter for the id. For example, https://localhost:8080/game?id=foobar
This would return a JSON object containing the entire game object:
You would then select the game status to render in the webpage.
GraphQL API
Using GraphQL, we can make a single request to all the data we need. The request would be a POST request to an endpoint looking something like: https://localhost:8080/graphql with the following in the body:
Which would return a JSON object containing the user and game containing only the parameters requested.
As you might imagine, this is extremely useful for requests in which you are requesting a large amount of data as you will only be getting the parameters requested and none others. This is also extremely useful for limiting the number of requests made to a server as multiple queries can be grouped together with ease.
Setting up the GraphQL API
Setup
To start off we should create a folder and initialize a NPM package inside it using the command
Next, we want to configure the project to use TypeScript. Create a file called tsconfig.json inside your project directory and add the following:
This allows for the TypeScript compiler to compile our code into JavaScript in the way we need. We have also included the options for rootDir and outDir, this means that all our source (TypeScript) files will be housed in the src folder and, when compiled, JavaScript will be emitted to the dist folder.
Next, we need to install all the required packages (NOTE: it’s important to install graphql and type-graphql at the versions displayed below to mitigate errors with Apollo.)
We also want to install a few dev dependencies to simplify our development process as well as to actually compile the TypeScript:
Next, inside package.json, we want to add the following to the "scripts" object:
start: Runs the compiled server
build: Compiles code inside ./src to ./dist
dev: Runs code while developing, restarts when .ts files are changed
Code
First, we want to create our main server file. Create a folder called src and create a file called index.ts inside of it.
At the top of the index.ts file, we will import the necessary modules.
For the sake of simplicity, we will keep all our code in the same file, however, it is always better to modularize code and split related classes and functions into separate files.
To start off, let’s create our User and Game classes which will be auto-generated into GraphQL types with TypeGraphQL.
User
Here is what the User class will look like:
TypeGraphQL will auto-generate a GraphQL schema type using this class which will look something like:
Game
The Game class implements nested objects, so, we will need to create classes for those as well. All of those classes and the Game class are shown below:
This will generate the following GraphQL types:
Next, we will create our resolvers for these classes. Resolvers in GraphQL are essentially the function that is called when a request is made. So, since we are calling getUser and getGame , we need to implement resolvers for both of these. For the sake of simplicity, I will hard code the “database”.
Here is what the resolver would look like:
This will generate the following in the GraphQL schema:
Next, we will create an IIFE (immediately invoked function expression) to run our server with. This is basically a function that calls itself. With this, we wont need to write a specific function to call, whenever we run our index.ts file, our server will be started. Inside of this function, we will generate our GraphQL schema and server and serve it with express.
Here is what this will look like:
And that’s it! Your GraphQL server is ready to go. You can test it out by running the command: npm run dev or yarn dev. This will expose an endpoint at http://localhost:8080/graphql. If you input this URL into a browser, it will open up to playground included with Apollo in which you can make GraphQL requests and debug your API.
It will look something like this:
Here you can write out GraphQL requests and test them out. It also auto-generates documentation for your API on the left hand side. To pull the same data as mentioned in our above example, we can write out the request and use variables:
To set the variables, we enter them as JSON in the bottom variables panel. Pressing run, we will see our response on the right hand side as depicted below:
Mutations
What if we wanted to update something in our “database”? With REST APIs, we’d make a POST, DELETE or PUT request, however, with GraphQL, all of these are grouped into one: mutations.
For the sake of our example, let’s say we wanted to update our user’s first or last name. We’d create another function in our resolver with the decorator @Mutation. Here is what this function would look like:
So, as you can see, GraphQL is a very simply yet very powerful tool and now you will be able to quickly setup and play around with a GraphQL API yourself.
I have included the entire index.ts file below, you can also find all the code on GitHub.