With the Mongoose adapter for Graffiti, you can use your existing Mongoose schema for developing a GraphQL application. If you need an introduction to GraphQL, our previous post helps you to get started with GraphQL.
We are going to cover the following topics:
- Introduction to Graffiti
- The Mongoose adapter
- Relay & GraphQL
- Getting started with Graffiti
- Graffiti TodoMVC – a Relay example
Introduction to Graffiti
At RisingStack, we usually don’t write boilerplate code. GraphQL is great, but manually specifying the schema can be painful. That’s the reason we created Graffiti.
Graffiti consists of two main components. You can use graffiti to add a GraphQL endpoint to your web server. Either you can use a schema generated by an adapter, or you can pass in your own. An adapter like graffiti-mongoose can generate the GraphQL schema from your database specific schema description.
The Mongoose adapter for Graffiti
Graffiti currently has an adapter for the Mongoose ORM – with more adapters to come later.
Graffiti Mongoose can help you to use your existing Mongoose schema to generate a Relay compatible GraphQL schema.
We will use the following schema throughout this blog post:
The generated GraphQL schema looks the following:
The road towards Relay compatibility
Relay is a framework for building data-driven React applications. You can declare your data requirements using GraphQL for each component and Relay handles the requests efficiently. Relay makes a few assumptions about the GraphQL schema that is provided by the GraphQL server.
The Node interface
Every type must implement the Node interface, which contains a single
id field. This is a globally unique identifier encoding the type and type-specific ID. This makes it possible to re-fetch objects using only the
Pagination and the Connection type
The pagination and slicing rely on the standardized
Connection type. We can use an introspection query to see what it looks like.
The edge type describes the collection, and the pageInfo contains metadata about the current page. We have also added a count field, which can be very handy in certain situations. Slicing is done via the passed in arguments:
before. For example, we could ask for the first two users after a specified cursor on the viewer root field.
Mutations like add, update and delete are also supported. Let’s try to add a new user!
As you can see, we just made a typo. We can fix the user’s name by using an update mutation.
Nice, isn’t it?
Most likely you’ll need some custom logic in your application. For example, to authorize a request or to filter certain fields before returning it to the client. You can specify pre- and post-resolve hooks to extend the functionality of Graffiti Mongoose.
You can add hooks to type fields and query fields (singular & plural queries, mutations) too. By passing arguments to the next function, you can modify the parameters of the next hook or the return value of the resolve function.
For example, this pre-mutation hook filters bad words.
Creating a GraphQL server
First, we need to define our Mongoose models.
We all like pets, right? For our application, we’ll keep track of users and pets. Let’s define the User and Pet models!
We can generate the GraphQL schema from the Mongoose models using graffiti-mongoose.
Now, we can add graffiti to the project.
Our server is ready to use. You can use GraphiQL, an in-browser GraphQL IDE, to explore our GraphQL API by navigating to localhost:3001/graphql
You can find examples for koa and hapi alongside express in the main repository.
To demonstrate the Relay compatibility, we also created a Relay application based on the well known TodoMVC. The source code can be found here.
You can take a look here if you want to try it out: http://graffiti-todo.herokuapp.com.
We work hard to make Graffiti and Graffiti Mongoose even better. Recently we did a full rewrite of both projects in ES2015/ES2016 to make the code more readable and easier to make improvements.
If you want to get involved in Graffiti, feel free to contribute to the projects on GitHub.