Welcome to part-2 of the series. This series have been inspired by this youtube tutorial from freecodecamp.
We will first add another type author to schema.js
The process is almost similar to the one for books type.
const graphql = require('graphql');
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLID, GraphQLInt } = graphql;
// Dummy data
var books = [
{ name: 'Name of the Wind', genre: 'Fantasy', id: '1' },
{ name: 'Two States', genre: 'Drama', id: '2' },
{ name: 'The Long Earth', genre: 'Sci-Fi', id: '3' },
];
var authors = [
{ name: 'Patrick Rothfuss', age: 44, id: '1' },
{ name: 'Chetan Bhagat', age: 45, id: '2' },
{ name: 'Terry Pratchett', age: 66, id: '3' }
];
const BookType = new GraphQLObjectType({
name: 'Book',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
genre: { type: GraphQLString }
})
});
const AuthorType = new GraphQLObjectType({
name: 'Author',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
age: { type: GraphQLInt }
})
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
book: {
type: BookType,
args: { id: { type: GraphQLID } },
resolve(parent, args){
return books.find(item => item.id === args.id);
}
},
author: {
type: AuthorType,
args: { id: { type: GraphQLID } },
resolve(parent, args){
return authors.find(item => item.id === args.id);
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
One thing to note that we have make the id as GraphQLID. The difference from GraphQLString is that, we can pass a number also in id.
The usual string will also work.
Next, we will make the relation between the book and author types. Each book have an author, so in book array we add a key authorId, for each object corresponding to the id in authors array.
Also, in BookType we are adding query to get the author by using the parent’s authorId.
…
…
var books = [
{ name: 'Name of the Wind', genre: 'Fantasy', id: '1', authorId: '1' },
{ name: 'Two States', genre: 'Drama', id: '2', authorId: '2' },
{ name: 'The Long Earth', genre: 'Sci-Fi', id: '3', authorId: '3' },
];
var authors = [
{ name: 'Patrick Rothfuss', age: 44, id: '1' },
{ name: 'Chetan Bhagat', age: 45, id: '2' },
{ name: 'Terry Pratchett', age: 66, id: '3' }
];
const BookType = new GraphQLObjectType({
name: 'Book',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
genre: { type: GraphQLString },
author: {
type: AuthorType,
resolve(parent, args){
return authors.find(item => item.id === parent.authorId);
}
}
})
});
…
…
Now, we can query in graphiql and get the author details also for a book.
Now, we will do the opposite. Each author have book, in fact each author can have many books. So, we have a new variable type called GraphQLList.
const graphql = require('graphql');
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLID, GraphQLInt, GraphQLList } = graphql;
// Dummy data
var books = [
{ name: 'Name of the Wind', genre: 'Fantasy', id: '1', authorId: '1' },
{ name: 'Two States', genre: 'Drama', id: '2', authorId: '2' },
{ name: 'The Long Earth', genre: 'Sci-Fi', id: '3', authorId: '3' },
{ name: 'The Colour of Magic', genre: 'Fantasy', id: '4', authorId: '3' },
{ name: 'The Light Fantastic', genre: 'Fantasy', id: '5', authorId: '3' },
{ name: 'Five Point something', genre: 'Drama', id: '6', authorId: '2' },
];
var authors = [
{ name: 'Patrick Rothfuss', age: 44, id: '1' },
{ name: 'Chetan Bhagat', age: 45, id: '2' },
{ name: 'Terry Pratchett', age: 66, id: '3' }
];
const BookType = new GraphQLObjectType({
name: 'Book',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
genre: { type: GraphQLString },
author: {
type: AuthorType,
resolve(parent, args){
return authors.find(item => item.id === parent.authorId);
}
}
})
});
const AuthorType = new GraphQLObjectType({
name: 'Author',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
age: { type: GraphQLInt },
books: {
type: new GraphQLList(BookType),
resolve(parent, args){
return books.filter(obj => obj.authorId === parent.id);
}
}
})
});
...
...
Now, on running our query for authors, we get all his books
Now, what if we want all the books in our database or all authors. It is very simple using GraphQL, as we need to just update our RootQuery with GraphQLList as below in schema.js.
…
…
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
book: {
type: BookType,
args: { id: { type: GraphQLID } },
resolve(parent, args){
return books.find(item => item.id === args.id);
}
},
author: {
type: AuthorType,
args: { id: { type: GraphQLID } },
resolve(parent, args){
return authors.find(item => item.id === args.id);
}
},
books: {
type: new GraphQLList(BookType),
resolve(parent, args){
return books;
}
},
authors: {
type: new GraphQLList(AuthorType),
resolve(parent, args){
return authors;
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
Now, a books query will return all books.
An authors query can also be done. We can also include the book.
Now, it’s time to store all our data into mongoDB. So, head over to https://mlab.com/ and login.
Then Create New mongoDB deployment.
Click on the Free plan.
Select a Region and then click Continue.
Give a name to your database and click continue.
In the next page, Submit the order.
Next, click on your new database.
In Users tab, click on Add database user. It will open a pop-up in which you need to provide a username and password.
Now, to connect to our database we need to use the query string highlighted below.
Now, open your terminal and stop nodemon and install mongoose.
Next, we add the code in App.js to connect to our database.
const express = require('express');
const graphqlHTTP = require('express-graphql');
const schema = require('./schema/schema');
const mongoose = require('mongoose');
const app = express();
mongoose.connect('mongodb://nabs:useyourown@ds159546.mlab.com:59546/graphql-react');
mongoose.connection.once('open', () => {
console.log('Conneted to database');
});
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
}));
app.listen(4000, () => {
console.log('Listening at port 4000');
});
The running nodemon, will show the success message.
Now, we need to create our mongodb schemas. So, go ahead and create a folder models inside server. Inside it we create two files — book.js and author.js
In author.js add below code to export an authorSchema.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const authorSchema = new Schema({
name: String,
age: Number
});
module.exports = mongoose.model('Author', authorSchema);
In book.js add below code to export an bookSchema.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bookSchema = new Schema({
name: String,
genre: String,
authorId: String
});
module.exports = mongoose.model('Book', bookSchema);
Next, head over to schema.js and delete the dummy data and all return statements with dummy data. We will add an mutation, which will be used to insert data in our database.
const graphql = require('graphql');
const Book = require('../models/book');
const Author = require('../models/Author');
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLID, GraphQLInt, GraphQLList } = graphql;
const BookType = new GraphQLObjectType({
name: 'Book',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
genre: { type: GraphQLString },
author: {
type: AuthorType,
resolve(parent, args){
//return authors.find(item => item.id === parent.authorId);
}
}
})
});
const AuthorType = new GraphQLObjectType({
name: 'Author',
fields: ( ) => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
age: { type: GraphQLInt },
books: {
type: new GraphQLList(BookType),
resolve(parent, args){
//return books.filter(obj => obj.authorId === parent.id);
}
}
})
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
book: {
type: BookType,
args: { id: { type: GraphQLID } },
resolve(parent, args){
//return books.find(item => item.id === args.id);
}
},
author: {
type: AuthorType,
args: { id: { type: GraphQLID } },
resolve(parent, args){
//return authors.find(item => item.id === args.id);
}
},
books: {
type: new GraphQLList(BookType),
resolve(parent, args){
//return books;
}
},
authors: {
type: new GraphQLList(AuthorType),
resolve(parent, args){
//return authors;
}
}
}
});
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addAuthor: {
type: AuthorType,
args: {
name: { type: GraphQLString },
age: { type: GraphQLInt }
},
resolve(parent, args){
let author = new Author({
name: args.name,
age: args.age
});
return author.save();
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery,
mutation: Mutation
});
Next, head over to graphiql to add an author with mutation.
Also, check in your mlab whether that author was added.
Now, we will add mutation to add a book.
...
...
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addAuthor: {
type: AuthorType,
args: {
name: { type: GraphQLString },
age: { type: GraphQLInt }
},
resolve(parent, args){
let author = new Author({
name: args.name,
age: args.age
});
return author.save();
}
},
addBook: {
type: BookType,
args: {
name: { type: GraphQLString },
genre: { type: GraphQLString },
authorId: { type: GraphQLID }
},
resolve(parent, args){
let book = new Book({
name: args.name,
genre: args.genre,
authorId: args.authorId
});
return book.save();
}
}
}
});
...
...
Next, head over to graphiql to add an book with mutation. Notice, that the authorId we have to get from mlab, from the newly created author.
Add some more book and then head over to mlab to verify your additions.
This concludes part-2 of the series. You can find code till here in the github link.
Top comments (0)