Table of Contents
For most of the cases defining a fixed schema when the application starts, by adding Query and Mutation types solely using schema language is good enough. But sometimes we might need to define a dynamic schema and we can achieve this by creating a new JS objects.
Construct dynamic schema for ‘User Greeting’ example.
Let’s get again to the ‘Greetings user’ example, because of it’s simplicity and define a Query
with field named greetingUser
which will accept userName
and bornMonth
parameters, first of type string
and the second of type int
and return userType
.
And the userType
will return greetingOne
which will simply say “Hello [userName]” and greetingTwo
that will let the user know how many months left till their next birthday. Both of type string.
./src/server.js
var express = require('express'); var graphqlHTTP = require('express-graphql'); var { buildSchema } = require('graphql'); var dogs = require('./src/models/mock_data/dogs.js'); const graphql = require('graphql'); // Define the User type var userType = new graphql.GraphQLObjectType({ name: 'UserType', fields: { greetingOne: { type: graphql.GraphQLString }, greetingTwo: { type: graphql.GraphQLString }, } }); // Define the Query type var queryType = new graphql.GraphQLObjectType({ name: 'Query', fields: { greetingUser: { type: userType, args: { userName: { type: graphql.GraphQLString }, bornMonth: { type: graphql.GraphQLInt } }, resolve: function (_, {userName, bornMonth}) { var date = new Date(); var daysLeft = bornMonth - (date.getMonth() + 1); daysLeft = daysLeft < 0 ? daysLeft + 12 : daysLeft; return { greetingOne: `Hello ${userName}`, greetingTwo: `Your birthday is comming in ${daysLeft} month(s)` }; } } } }); var schema = new graphql.GraphQLSchema({query: queryType}); // Logger middleware var logger = function(req, res, next) { console.log("GOT REQUEST >", req.ip); next(); // Passing the request to the next handler in the stack. } var app = express(); app.use(logger); app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true, })); app.listen(4000); console.log('Running a GraphQL API server at localhost:4000/graphql');
what we just did:
– we defined the user type which is pretty self explanatory (Lines 8-14)
– then we created the query type, that has these parameters:
– type
which is the return type, in this case userType
– args
is the input parameter types.
– resolve
is the resolver function.
Transform Dogs catalog to use dynamic schema.
Creating the dog type
var dogType = new graphql.GraphQLObjectType({ name: 'dogType', fields: { id: { type: graphql.GraphQLString }, breed: { type: graphql.GraphQLString }, displayImage: { type: graphql.GraphQLString }, } });
Creating the query type
// Define the Query type var queryType = new graphql.GraphQLObjectType({ name: 'Query', fields: { getDogByBreed: { type: dogType, args: { breed: { type: graphql.GraphQLString } }, resolve: function (_, {breed}) { var result = dogs.find(function(dog){ return breed == dog.breed; }); return result; } } } });
Creating a mutation type
... addDogBreed: { type: graphql.GraphQLString, args: { id: { type: graphql.GraphQLString }, breed: { type: graphql.GraphQLString }, displayImage: { type: graphql.GraphQLString } }, resolve: function (_, {id, breed, displayImage}) { dogs.push({ id: id, breed: breed, displayImage: displayImage }); return "OK!"; } } ...
Adding the query schema
... var schema = new graphql.GraphQLSchema({query: queryType}); ... app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true, })); ...
Putting it all together
var express = require('express'); var graphqlHTTP = require('express-graphql'); var { buildSchema } = require('graphql'); var dogs = require('./src/models/mock_data/dogs.js'); const graphql = require('graphql'); // Define the dogs type var dogType = new graphql.GraphQLObjectType({ name: 'dogType', fields: { id: { type: graphql.GraphQLString }, breed: { type: graphql.GraphQLString }, displayImage: { type: graphql.GraphQLString }, } }); // Define the Query type var queryType = new graphql.GraphQLObjectType({ name: 'Query', fields: { getDogByBreed: { type: dogType, args: { breed: { type: graphql.GraphQLString } }, resolve: function (_, {breed}) { var result = dogs.find(function(dog){ return breed == dog.breed; }); return result; } }, addDogBreed: { type: graphql.GraphQLString, args: { id: { type: graphql.GraphQLString }, breed: { type: graphql.GraphQLString }, displayImage: { type: graphql.GraphQLString } }, resolve: function (_, {id, breed, displayImage}) { dogs.push({ id: id, breed: breed, displayImage: displayImage }); return "OK!"; } } } }); var schema = new graphql.GraphQLSchema({query: queryType}); // Logger middleware var logger = function(req, res, next) { console.log("GOT REQUEST >", req.ip); next(); // Passing the request to the next handler in the stack. } var app = express(); app.use(logger); app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true, })); app.listen(4000); console.log('Running a GraphQL API server at localhost:4000/graphql');