express-graphql-with-mongoose
express-graphql-with-mongoose copied to clipboard
Simple Graphql express example for learning purpose. in this project, i also provide the concept how to interact with mongodb and graphql with express server. developer also use this for small applica...
GraphQL practical example with express-graphql and mongoose

GraphQL developed by Facebook in 2012 and publicly available in 2015. GraphQL is alternative of REST full web service. It allows clients Query with flexible data structure which are required for client. It also support the data manipulation and modification functionlaity named mutation Like rest api. GraphQL provide official middleware for express server named express-graphql.
Over the past two month, I tried to learn about graphql and graphql connection with database using express js. I read some blogs and article. Most of the author provide the example or tutorial which graphql is related to static json data. Some blog are provide simple example with one graphql's type.
So I am tried to read those blogs and graphql documentation again and again. Last tow week ago, I think about some idea about how i connect the mongodb with graphql using express js as web server. create the example which provides CRUD operation functionality with tow mongodb collections with one to many relation. this project will provide the idea about how developer handle the one to many and many to many relation graphql's type using mongoose and graphql-express.This Project will also show the path how to build better web service structure using graphql with express js.
Installation instructions
- clone the repository
git clone https://github.com/tariqulislam/express-graphql-basic-server.git - For Yarn run command
yarn install - Or for npm run command
npm install
Project Structure
EXPORESS-GRAPHQL-WITH-MONGOOSE
|--------------
|--| config
|----| database.js (database configuration file)
|--|db (mongodb exported collection)
|----| <mongodb collection>.json (mongodb exported file)
|--| src (Project soruce file directory)
|----| graphql (All graphql related file directory)
|------| mutations (All graphql mutation related file directory)
|--------| <Type Wise Mutation>.js (Graphql type wise mutation files)
|--------| index.js (export all mutation to other module by this file)
|------| queries (All GraphQL Query related files)
|--------| <GraphQL type file>.js (Individual Graphql type related file)
|--------| index.js (GraphQL Root Type file)
|----| models (All mongoose ODM related file)
|------| <mongoose model>.js (mongoose model and schema related file)
|----| schema.js (GraphQL Schema building file)
|--| .env (node js environment variable related file)
|--| index.js (main file for run web server and connection mongoose create GraphQL Endpoint)
Prerequsite and configurations
- Install the
mongodbandStudio 3Tnon commercial version. - Create Database to mongodb named
graphqltest - Add username and password to mongodb and provide all permission to database.
- Grant all permission to user.
- Import
jsonfile fromdbfolder tographqltestdatabase. - Change the
.envfile for database configuration - Run the command
yarn startornpm start
DATABASE_HOST=localhost
DATABASE_PORT=27017
DATABASE_USER=<username>
DATABASE_PASS=<password>
DATABASE_NAME=graphqltest
Introductions and knowladgebase
- GraphQL
- express JS
- dotenv
- mongoose
- Graphqli
- nodemon
What is graphql
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools!alt text.
What is graphql-express
GraphQL HTTP server with any HTTP web framework that supports connect styled middleware, including Connect itself, Express and Restify.
What is Mongoose
Mongoose is an object data modeling (ODM) library that provides a rigorous modeling environment for your data, enforcing structure as needed while still maintaining the flexibility that makes MongoDB powerful.
Express JS
Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
Sample coding for create graphql api for client
Create the mongoose schema for database interactions
- Go to
src/modelsfolder - Create file
Author.jsandPost.js
// src/models/Author.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const authorSchema = new Schema({
name: { type: String },
email: {type: String, required: true, unique: true}
});
const Author = mongoose.model('Author', authorSchema);
module.exports = Author;
// src/models/Post.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const postSchema = new Schema({
author_id: Schema.Types.ObjectId,
title: String,
category: String,
body: String
});
const Post = mongoose.model('Post', postSchema);
module.exports = Post;
this code snappit contains the model defination for mongodb using mongoose ODM.
- first we add
mongooseby addingjavascript const mongoose = require('mongoose'); - then add the
javascript const Schema = mongoose.Schema;schema for support different datatype and constraint ofmongoose - Schema defination for
authorSchemaandpostSchemacontains themongodbcollectioninformation
What is Schema in Graphql?
GraphQL has its own type language that’s used the write GraphQL schemas: The Schema Definition Language (SDL). Schema contains the some attributes named.!GraphQL Documentation
- Query
- Mutation
- Subscription
What is Type in graphql?
The most basic components of a GraphQL schema are object types, which just represent a kind of object you can fetch from your service, and what fields it has. In the GraphQL schema language, we might represent it like this!GraphQL Documentation:
type PostType {
id: ID!
title: String!
body: String!
author: [AuthorType]!
}
AuthorType: is a Graphql Object Typeid,titleandbody,AuthorTypeis field name of Object TypeStringandIDisDataTypeof thefield. this type is called asScalarTypeand- After
DataType!symbol meansnon-nullable [AuthorType]!meansarrayofAuthorTypeobject which is embedded withAuthorTypeObject Type
How to Create Type of ObjectType in Graphql?
const { GraphQLString, GraphQLObjectType, GraphQLNonNull } = require('graphql');
const AuthorType = new GraphQLObjectType({
name: 'AuthorType',
description: "This represent an author",
fields: () => ({
_id: {type: new GraphQLNonNull(GraphQLString)},
name: {type: new GraphQLNonNull(GraphQLString)},
email: {type: GraphQLString}
})
});
module.exports = AuthorType;
express-graphqlprovide theGraphQlObjectTypewhich is provide all functionality of graphqlTypeandQuery- I define
AuthorTypeas aGraphQLObjectTypeatsrc/graphql/queries/AuthorType.js
const { GraphQLString, GraphQLObjectType, GraphQLNonNull } = require('graphql');
const Author = require('../../models/Author');
const AuthorType = require('./AuthorType');
const mongoose = require('mongoose');
const PostType = new GraphQLObjectType({
name: 'PostType',
description: "This is resent post",
fields: () => ({
_id: {type: new GraphQLNonNull(GraphQLString)},
title: {type: GraphQLString},
body: {type: GraphQLString},
author_id: {type: GraphQLString},
author: {type: AuthorType, resolve: async function (post) {
var authors = await Author.findById(mongoose.Types.ObjectId(post.author_id))
if(!authors) {
throw new Error('Error')
}
return authors
}}
})
});
module.exports = PostType
- define
PostTypevariable atsrc/graphql/queries/PostType.jsfile, which contains theGraphQLObjectType. GraphQLObjectTypehas argumentObjectwhich contains:
{
name: `<Name of the GrapQLObjectType or Graphql Type>`,
description: `<Description of the GraphQLObjectType`>,
fields: () => `(function which contains return the fields of the GraphQLObjectType)`{
type: `<Datatype of the Fields>`
resolve: `(function for resolve the field from api or database or from ORM or ODM)`
}
}
- at
PostTypegraphql object type, I have added theauthorfield andresolvefunction to resolve the field information from mongodb database usingmongoosemodel namedAuthormodel - I have use
asyncfunction to resolve theauthorfield var authors = await Author.findById(mongoose.Types.ObjectId(post.author_id))returnauthorinformation related to specificpost- to handle the error i have to throw the
Errorobject, which object has noauthorinformation bythrow new Error('Error') - or
return authorswhich containsAuthorTypegraphql Object Type Information.
What is Root Type in GraphQL?
At the top level of every GraphQL server is a type that represents all of the possible entry points into the GraphQL API, it's often called the Root type or the Query type.!GraphQL Documentation
How to Create Root Type for Schema by express-graphql?
In this project I have create the root type at file src/graphql/queries/index.js
// src/graphql/queries/index.js
const { GraphQLList, GraphQLObjectType } = require('graphql');
const Author = require('../../models/Author')
const Post = require('../../models/Post')
const PostType = require('./PostType');
const AuthorType = require('./AuthorType')
const BlogQueryRootType = new GraphQLObjectType ({
name: 'BlogAppSchema',
description: "Blog Application Schema Query Root",
fields: () => ({
authors: {
type: new GraphQLList(AuthorType),
description: "List of all Authors",
resolve: async function () {
return await Author.find({}, (err, auth) => {
});
}
},
posts: {
type: new GraphQLList(PostType),
description: "List of all posts",
resolve: async function () {
var posts = await Post.find({})
return posts;
}
}
})
});
module.exports = BlogQueryRootType
BlogQueryRootTypeis a root type and also aGraphQLObjectTypewhich contains all the attribute and functions like otherGraphQLObjectType.- In
filedsis functions which contains all theQueryof the Schema. For Every GraphQLfieldhas its ownresolveoptions. authorsandpostsfieldsresolvelist of a thoseGraphQLObjectType.
What is Mutations in GraphQL?
In REST, any request might end up causing some side-effects on the server, but by convention it's suggested that one doesn't use GET requests to modify data. GraphQL is similar - technically any query could be implemented to cause a data write. However, it's useful to establish a convention that any operations that cause writes should be sent explicitly via a mutation.
Just like in queries, if the mutation field returns an object type, you can ask for nested fields. This can be useful for fetching the new state of an object after an update.!GraphQL Documentation
How to Create Mutation by express-graphql?
- In this project I have create the directory
src/graphql/mutations. - Then I have create the file named
AuthorMutation.jsandPostMutation.jsfileimportthe graphql express functions and library andimportmongoosemodels for mutation operations.
// src/graphql/mutations/AuthorMutation.js
var {GraphQLNonNull, GraphQLString} = require('graphql');
var AuthorType = require('../queries/AuthorType');
var Author = require('../../models/Author')
- At
AuthorMutations.jsfile have added the three functions for mutations.
// src/graphql/mutations/AuthorMutation.js
const addAuthor = {
type: AuthorType,
args: {
name: {
name: 'name',
type: new GraphQLNonNull(GraphQLString)
},
email: {
name: 'email',
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: async function (root, params) {
const uModel = new Author(params);
const newAuthor = await uModel.save();
if(!newAuthor) {
throw new Error('Error')
}
return newAuthor
}
}
- for
addAuthormutation type contains two attributes and oneresolvefunction typeattribute value will be any type ofGraphQLObjectType. I have addedAuthorTypegraphql Object type foraddAuthormutation.argsattribute contains the paramter for this mutation. we can defind the each argument which contains:
<argument_name>: {
name: <argument_name> // Optional,
type: <GraphQL_type> // `GraphQLNonNull` for checking the null value
}
-
resolvefunction using for resolve the mutations. which contains the all the functionality to change or effect themodelsordata. I have usemongoosesavefunction to save the new author to mongodb database. also useasyncfunction to handle the mongodb operations. -
Mutation for update the author information, i write the code to
AuthorMutation.jsfile. the function isupdateAuthor. which contains similar attribute likeaddAuthor:
// src/graphql/mutations/AuthorMutation.js
const updateAuthor = {
type: AuthorType,
args: {
_id: {
name: '_id',
type: new GraphQLNonNull(GraphQLString)
},
name: {
name: 'name',
type: GraphQLString
},
email: {
name: 'email',
type: GraphQLString
}
},
resolve: async function(root, param) {
let updateAuthor = {};
if(param.name) {
updateAuthor.name = param.name
}
if(param.email) {
updateAuthor.email = param.email
}
const uAuthor = await Author.findByIdAndUpdate(param._id, updateAuthor, {new: true})
console.log(uAuthor)
if(!uAuthor) {
throw new Error('Error')
}
return uAuthor
}
}
- For Delete author has similar attribute like
addAuthor. the code snippet are shows below:
// src/graphql/mutations/AuthorMutation.js
const deleteAuthor = {
type: AuthorType,
args: {
_id: {
name: '_id',
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: async function (root, param) {
const deleteAuthor = await Author.findByIdAndRemove(param._id)
if(!deleteAuthor) {
throw new Error('Error');
}
return deleteAuthor
}
}
- then
exportthose functions at end ofAuthorMutation.jsfile:
// src/graphql/mutations/AuthorMutation.js
module.exports = {addAuthor, updateAuthor, deleteAuthor}
- Similar way i also create the
PostMutation.jsfile to add themutationfunctionality:
// src/graphql/mutations/PostMutation.js
var {GraphQLNonNull, GraphQLString} = require('graphql')
var Post = require('../../models/Post');
var PostType = require('../queries/PostType');
const createPost = {
type: PostType,
args: {
title: {
name: "title",
type: new GraphQLNonNull(GraphQLString)
},
author_id: {
name: "author_id",
type: new GraphQLNonNull(GraphQLString)
},
body: {
name: "body",
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: async function(root, param) {
const postModel = new Post(param);
const savePost = await postModel.save();
if(!savePost) {
throw new Error('Error')
}
return savePost;
}
}
const updatePost = {
type: PostType,
args: {
_id: {
name: "_id",
type: new GraphQLNonNull(GraphQLString)
},
author_id: {
name: "author_id",
type: GraphQLString
},
title: {
name: "title",
type: GraphQLString
},
body: {
name: "body",
type: GraphQLString
}
},
resolve: async function (root, param) {
let updatePost = {};
if(param.author_id) {
updatePost.author_id = param.author_id;
}
if(param.title) {
updatePost.title = param.title
}
if(param.body) {
updatePost.body = param.body
}
const updatePostInfo = await Post.findByIdAndUpdate(param._id,updatePost,{new: true});
if(!updatePostInfo) {
throw new Error('Error');
}
return updatePostInfo;
}
}
const deletePost = {
type: PostType,
args: {
_id: {
name: "_id",
type: new GraphQLNonNull(GraphQLString)
}
},
resolve: async function (root, param) {
const deletePost = await Post.findByIdAndRemove(param._id);
if(deletePost) {
throw new Error('Error');
}
return deletePost;
}
}
module.exports = {createPost, updatePost, deletePost}
- then Create
index.jsfile which will export all themutationsfunctions and objects
// src/graphql/mutations/index.js
var { addAuthor, updateAuthor, deleteAuthor } = require('./AuthorMutation');
var { createPost, updatePost, deletePost} = require('./PostMutation')
module.exports = {
addAuthor,
updateAuthor,
deleteAuthor,
createPost,
updatePost,
deletePost
}
How to Create Schema in express-graphql?
Then I have create the schema js file to src/graphql/schema.js which contains all the graphql Query and Mutation.
// src/graphql/schema.js
const { GraphQLObjectType,GraphQLSchema } = require('graphql');
const mutation = require('./graphql/mutations/index')
const BlogQueryRootType = require('./graphql/queries/index')
const BlogAppSchema = new GraphQLSchema({
query: BlogQueryRootType,
mutation: new GraphQLObjectType({
name: 'Mutation',
fields: mutation
})
});
module.exports = BlogAppSchema;
GraphQLSchemacontains thequeryandmutationattribute or object.queryattribute containsroot typefor graphql which i created atsrc/graphql/queries/index.jsfile.mutationattribute is also aGraphQLObjectType, which contains two attribute.
{
name: <name of the mutation>
fields: <Main mutations Object>
}
- I have added the main
mutationobjects which are exported atsrc/graphql/mutations/index.js
Call the Graphql Schema to http endpoint of express js:
graphql-expresswhich is a middleware of express and graphql.- check endpoint using
schema.jsschema atindex.jsroot of the project directory.
// index.js
...
const schema = require('./src/schema');
...
...
app.use('/', graphQLHttp({
schema: schema,
graphiql: true
}));
- Run the Application by
npm startor if you are usingyarncommand will beyarn start
Query and Mutation Example
- Mutation Example for Adding the Author

- Query Example for Show All Author

- Mutation for update Author Information

- Mutation for delete Author

- Mutation for create the post info

- Query for get all post with author data

- Update Post Information
