Step-by-step: Building a Node.js server (2021 edition) — Part 3/4 — The API

Koa.js, GraphQL, MongoDB, Docker, Mocha, Typescript

GraphQL Code-Generator

npm i graphql mongodb apollo-server-koa apollo-datasource-mongodb @graphql-tools/schema @graphql-codegen/typescript-mongodbnpm i -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers @types/mongodb
"codegen": "graphql-codegen --config codegen.yml"

Connect to the Apollo Server and Database instance

The code architecture
Class diagram of the server

Database managers

  1. We’re using the MongoDB driver for NodeJS to instantiate a MongoClient. The methods are pretty standard lifecycle methods, to start and stop the client. We can’t really connect to the client in the constructors because the connect() method is async. So we need to call a dedicated start() method manually.
  2. To build the connection string needed by MongoDB to connect to our database container, we’re using the environment variables we defined in the .env file.

Apollo Server manager

  • For the findOne method, we are basically encapsulating MongoDB’s NodeJS driver’s findOne method to fetch users with a query.
  • Same or the insertOne method, except that instead of a query we’re passing arguments (the new user) to MongoDB’s insertOne method.
  • Note that we’re importing the UserDbObject from our generated types. 😎
  • There’s some basic error management but feel free to add more checks.
  • The DIRECTIVES declaration is needed by the code generator to properly map the entities. That’s why we saved this package in the regular dependencies (it is needed at runtime).
  • Our GraphQL clients will be able to query user(name: $name) and to call the addUser(name: $name) mutation.
  • We’re using the datasources we defined in src/datasource/User.ts to link our GraphQL API to the database and return something to the clients.
  • Line 24, we’re instantiating the actual ApolloServer. We are passing it our schema, a context pre-populated by Koa, the datasources and an error handler callback.
  • Ideally we would add authentication and populate some loggedUser field in the context, but that’s out of this tutorial’s scope. See Apollo’s tutorial for how to do that.

Run our GraphQL and MongoDB powered back-end

# Write your query or mutation here
mutation AddUser($name:String!) {
addUser(name:$name) {
"name": "Batman"
# Write your query or mutation here
query User($name:String!) {
user(name:$name) {



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store