GraphQL

There are many advantages to GraphQL but predictability is one of the best.

Send a GraphQL query to your API and get exactly what you need, nothing more and nothing less. GraphQL queries always return predictable results.

Apollo is one of the most popular libraries to build a GraphQL API today. It works well with Node and React. We will be using it. We will also use TypeGraphQL to define our schema with TypeScript classes.

From now, we are building our app. So let's remove the migration until we need it. We'll keep one for reference.

sequelize.sync({ force: true }) will automatically create the required tables for you.

001_example.ts
import { QueryInterface } from "sequelize";

module.exports = {
  // change the database schema
  async up(query: QueryInterface) {
    // add migration here
  },

  // revert in case it goes wrong
  async down(query: QueryInterface) {
    // revert
  }
};

Move from models to entities

The vast majority of GraphQL queries and mutations are to interact with the database. To avoid repeating ourselves, we will define your models and GraphQL schema with the same files.

Rename models to entities to reflect the semantic of our files.

Change sequelize.ts import path import * as models from "./entities";.

Build the GraphQL Schema

Install dependencies

Following the TypeGraphQL documentation, we have to import reflect-metadata before we use/import type-graphql or our resolvers.

Update Link.tsto add ObjectType and Field.

Create a resolver in a new folder GraphQL inrouters as well as resolvers to keep things tidy.

For now, we're just going to return a hardcoded array of Links

Our new GraphQL router will build the schema

Don't forget to add it to app.ts

We are now able to send GraphQL queries. Let's open http://localhost:3000/graphql and see if it works.

It works!

Return data from the database

Update the containers with Link

then set our Link entity when we declare it

and use it in our resolver

Pagination

Results should always be paginated for performance reasons. It's good practice to add it at the beginning.

We are going to create 2 helpers in routers/GrapqhQL.

The first one, PaginatedResponse.ts, generate a new class with to attributes:

  • items the data returned. In this case, it will be Link.

  • total the amount of items available to query.

  • hasMore will be true if you can request more items.

The second one, PaginatedArgs.ts, adds query arguments:

  • limit how many items to retrieve.

  • offset how many items to skip.

We have to set "declaration": false in tsconfig.json.

Let's modify the Linkresolver to use it:

Writing integration tests

We can use createTestClient from ApolloTesting.

Add the requires dependencies:

  • Create a server

  • Build the schema with the resolver

  • Send the query

Conclusion

We have seen how to:

  • Retrieve and create rows in the database

  • Paginate the results

  • Write isolated integration tests for the resolvers

The next step is now to add user authentication and make sure only owners can access their links.

graphql branch available on GitHub.

graphql branch available on GitHub.

Last updated

Was this helpful?