apollo-mongo-template

🌿 A template to create an Apollo Server with MongoDB.


Project maintained by yvesgurcan Hosted on GitHub Pages — Theme by mattgraham

Main dependencies

Setup

You need node, npm, and mongod (see instructions) installed globally on your machine in order to run this project.

All other dependencies are installed at the project level:

npm i

Development

Once you’ve installed all dependencies, type the following command to get started:

npm start

You can start the service on its own with npm run start:service or the database only at npm run start:db.

API playground and documentation

Once the server is up and running, you will be able to explore the API at http://localhost:4001/ thanks to GraphQL Playground

Click on the Schema and Docs tabs on the right to find the API documentation.

Feel free to write queries and mutations in the space on the left, see the results returned by the API, and take advantage of the auto-complete feature 😃.

Keep in mind that GraphQL typically uses a single endpoint to handle all the requests.

Design

This API is designed with its data at the center. For each data type, you will find the following structure in the source code:

    dataType
    ├── dataType.controller.js
    ├── dataType.model.js
    ├── dataType.resolver.js
    ├── dataType.schema.js

Schema

The schema is a self-documenting script that visually represents the interface and data structure exposed for each data type. In each *.schema.js file, you will find the following elements:

The fact that GraphQL is a strongly typed query language provides the same advantage as other strongly typed languages when it comes to developing (and discovering) the API.

Additionally, the ability to carefully choose which database fields are exposed for each data type minimizes the need to sanitize the input.

Model

The model is the representation of this data type from the perspective of the database. Mongoose allows us to go further into shaping our data and making sure that it stays tidy.

A couple of the features that help us handling data for this application are the following:

Resolver map

Resolvers are a central piece of GraphQL. In this application, the resolver map of each data type (*.resolver.js) simply represents the connection between what we call the controller and the schema.

Controller (the real resolvers)

You will find the business logic that relates to a particular data type in the controller. Typically, this is where the CRUD operations happen, including interactions with MongoDB.

The signature of each function (aka resolver) looks like this example:

    resolver(parent, arguments, context)

The value returned by the function is essentially the object that forms the core of the response of the Apollo Server to the client.

Configuration

Environment-specific variables can be found in the config folder at the root of the project.

The logic that relates to the configuration of the API can be found in the various files at the root of the source folder. The following files are particularly noteworthy:

    src
    ├── resolvers.js
    ├── schema.js
    ├── database.js
    ├── server.js
    ├── index.js
    ├── util.js

In addition to the API configuration, this project also contains at its root several config files related to the tools that are used to develop it:

Integration tests

npm test

Running the tests will instantiate a separate Apollo Server and a database for test purposes. In order to pass a test, the output of the query must match the snapshot that was previously saved. To update snapshots:

npm run test:update

Since MongoDB relies on unique identifiers to avoid collisions, tests that involve foreign keys would systematically fail (snapshots would never match). Therefore, the test database relies on traditional auto-incrementing identifiers instead. The production database still relies on unique identifiers.