How To Create a GraphQL Schema With GraphQL.js and Express?
In this post, we will learn how to create a GraphQL Schema using GraphQL.js. We will use the express-graphql package to handle the webserver part of the application.
Join the DZone community and get the full member experience.
Join For FreeIn case you are completely new to GraphQL, I will recommend you to start with our Introduction to GraphQL or GraphQL Core Concepts
A schema is the core component of a GraphQL application. It defines the capabilities of the GraphQL application. To elaborate further, a GraphQL schema is like a description of the data available from your application. It also defines the various queries and mutations that clients can use to interact with the server. In a way, the schema is the heart of a GraphQL application.
1 – Setting Up the Project
We will first create a project and install the express, graphql-express, and graphql packages. You can read more about these packages by going through this post about building your first GraphQL server.
Then, we will create a file named server.js to handle the configuration and startup of our application.
See below:
server.jsconst express = require('express');
const { graphqlHTTP } = require('express-graphql');
const schema = require('./schema/schema')
var app = express();
app.use("/graphql", graphqlHTTP({
schema,
graphiql: true
}));
app.listen(4000);
console.log('GraphQL API server available at http://localhost:4000/graphql');
You can ignore the third line for the time being where we require a schema file. We will be creating it in the next section. Basically, we import the schema and provide it to the graphqlHTTP() function. Also, we set the GraphiQL property as true. Setting this to true enables the GraphQL playground where we can test our GraphQL queries. Finally, we start the application to listen on port 4000.
2 – Creating Book Object Type
Now, we create the schema file for the application.
To demonstrate how a GraphQL Schema works, we will take the example of a Book entity.
See below:
schema.jsconst graphql = require('graphql');
const { GraphQLObjectType, GraphQLString } = graphql;
const BookType = new GraphQLObjectType({
name: 'Book',
fields: () => ({
id: {type: GraphQLString},
title: {type: GraphQLString},
genre: {type: GraphQLString}
})
})
We first get the reference to the GraphQL package and use ES6 object destructuring to pull out GraphQLObjectType and GraphQLString from the GraphQL package.
Then, we create a new GraphQLObjectType. The constructor takes an object as input. It has two properties – the name of the object type (in this case, we call it Book) and fields that are part of the object. There are three fields – id, title, and genre. All of these are of type GraphQLString. The GraphQL package has similar types for other primitive data types such as integer, boolean, and so on.
3 – The Root Query
The next step is to create the root query.
A root query is nothing but an entry point to our application. There can be multiple root queries in an application depending on the needs of the client.
For this example, we create a root query to fetch a book based on its id.
schema.jsconst RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
book: {
type: BookType,
args: {id: {type: GraphQLString}},
resolve(parent, args) {
return _.find(books, {id: args.id})
}
}
}
})
As you can see, we create another GraphQLObjectType. This time the name of the object is RootQueryType. The fields are basically the queries supported by our application.
For example, we support a query named book. The type property denotes the type of data that this query supports (in this case, it is the BookType. The args denote the type of input arguments to the query. In other words, the id of the book.
Lastly, we have the resolve() function. This function basically resolves the query and returns a response. To resolve the query, this function may reach out to a database or some other service. In this example, we use lodash to search a list of hard-coded books. Below is the complete code for the same.
schema.jsconst graphql = require('graphql');
const _ = require('lodash')
const { GraphQLObjectType, GraphQLString } = graphql;
var books = [
{id: '1', title: 'The Foundation', genre: 'Science Fiction'},
{id: '2', title: 'The Fellowship of the Ring', genre: 'Fantasy'},
{id: '3', title: 'The Eye of the World', genre: 'Fantasy'}
]
const BookType = new GraphQLObjectType({
name: 'Book',
fields: () => ({
id: {type: GraphQLString},
title: {type: GraphQLString},
genre: {type: GraphQLString}
})
})
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
book: {
type: BookType,
args: {id: {type: GraphQLString}},
resolve(parent, args) {
return _.find(books, {id: args.id})
}
}
}
})
4 – Creating GraphQL Schema
We now have all the pieces to create a GraphQL Schema.
Below is the final code of the schema.js file.
schema.jsconst graphql = require('graphql');
const _ = require('lodash')
const { GraphQLObjectType, GraphQLString, GraphQLSchema } = graphql;
//Dummy data for demo purpose
var books = [
{id: '1', title: 'The Foundation', genre: 'Science Fiction'},
{id: '2', title: 'The Fellowship of the Ring', genre: 'Fantasy'},
{id: '3', title: 'The Eye of the World', genre: 'Fantasy'}
]
//This is the type of data supported by the queries
const BookType = new GraphQLObjectType({
name: 'Book',
fields: () => ({
id: {type: GraphQLString},
title: {type: GraphQLString},
genre: {type: GraphQLString}
})
})
//Each field is a type of root query. In other words, all are entry points into the Graph
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
book: {
type: BookType,
args: {id: {type: GraphQLString}},
resolve(parent, args) {
return _.find(books, {id: args.id})
}
}
}
})
//Initialize and export the schema
module.exports = new GraphQLSchema({
query: RootQuery
})
As you can see, we also grab the GraphQLSchema property from the GraphQL package and use to it initialize a new schema. The input to the constructor object is nothing but RootQuery. We use module.exports to export the schema so that it will be available in the server.js.
5 – Testing the GraphQL Schema
We can now use the GraphiQL interface to trigger a query with a particular book id as input.
See the above screenshot where we trigger the query and get the response from the hard-coded books array. As you can see, the book object is wrapped within the top-level data object.
If we request data for an id that is not present, we get a null object as below:
{
"data": {
"book": null
}
}
Conclusion
With this, we have learned how to create a GraphQL Schema with GraphQL.js and Express. We used GraphQLObjectType to create the GraphQL data object and the GraphQL query type.
Want to learn more about GraphQL, you can check out this post on GraphQL Architectural Patterns.
If you have any comments or queries about this post, please feel free to mention them in the comments section below.
Published at DZone with permission of Saurabh Dashora. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments