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');