Write GraphQL APIs on Node with MongoDB
source link: https://www.tuicool.com/articles/hit/2i6zm22
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Write GraphQL APIs on Node with MongoDB
In a REST API based app, the server defines the shape and size of the resource provided by an endpoint. So any request sent to a server will return a lot of data, sometimes more than desired.
GraphQL solves this problem by giving us the ability to define exactly what data we need from the server while also allowing us the freedom to request as much or as little data as you want.
In this post, you will learn how to set up your GraphQL server with Node and Express persisted by MongoDB. You will also see how to create mutations that can update and delete data, queries to load specific data. You will also see how to connect GraphQL with MongoDB using Mongoose.
Getting Started
Create a new directory in your system:
$ mkdir hero-gql $ cd hero-gql
Inside, install a couple of developer dependencies:
$ yarn add babel-cli babel-preset-env babel-preset-es2015 babel-preset-stage-2 babel-register nodemon -D
Here, babel is used to transpile the ES6 code to ES5.
Now create a babel configuration file called .babelrc
in the directory. Inside this file, write:
{"presets": ["env", "stage-2"]}
Inside the package.json
file, write the scripts
and main
as given below:
{ "main": "src/app.js", "scripts": { "start": "nodemon src/app.js --exec babel-node --presets env,stage-2", "build": "babel src -d dist --source-maps", "serve": "node dist/app.js" }, // leave everything else as it is }
Creating an Express Server in Node
Express is a flexible Node framework that provides us with robust features for web app developement.
To create an Express server for your app, first install Express as a dependency in your system.
Now create a new folder called src
with a file named app.js
inside it. Write the following code inside it.
Run start
script using NPM/Yarn on your command terminal and see your code work!
GraphQL HTTP Server
To create a GraphQL HTTP Server, we first need to install express-graphql
, graphql
, and graphql-tools
as dependencies in our project.
$ yarn add express-graphql graphql-tools graphql
In the app.js
file, import graphqlHTTP
from the express-graphql
package.
import graphqlHTTP from 'express-graphql';
Use the graphqlHTTP
function inside the file like this:
const schema = {}; app.use('/graphql', graphqlHTTP({ graphiql: true, schema }));
Re-run the start
script using NPM/Yarn, and go to localhost:3000/graphql
in your browser.
What you will get on your browser is called GraphiQL. It is a new tool created by Facebook to test GraphQL endpoints, queries, and mutations.
Don’t worry about the error
in GraphiQL. We are getting it because we haven’t yet defined a valid schema object.
Creating A Valid Schema Object
The schema
is a model of the data that can be fetched using the GraphQL server. It defines the queries that a client can make in GraphQL, the types of data that can be fetched from the server, and the relationships that can exist between different types of data.
Currently in our app, we have set the schema
as an empty object, which is not a valid thing to do.
Inside the src
folder, and create a couple of files inside it.
schema.js resolvers.js
Inside the schema.js
file, write the following code:
I am importing the makeExecutableSchema
from the graphql-tools
package. We need to use this method to create the GraphQL schema
. I am also importing the resolvers
that will be created inside resolvers.js
file.
Lets also define the typeDefs
. This will contain a Query
type that defines the name
field as a String
type.
Finally, we export the schema
object with the help of makeExecutableSchema
. The schema
object takes in typeDefs
and the resolvers
.
Inside the resolvers.js
file, create a resolvers
object like this:
export const resolvers = { Query: { name (root, args, context, info) { return 'Rajat S'; }, }, };
The resolvers
object takes in four arguments — root
, args
, context
, and info
. For now, the object returns a simple string.
We now need to hook this up with the app.js
file. First, import the schema
object into this file. Also remove the line const schema = {};
.
import schema from './schema';
Re-run the start
script using NPM/Yarn, and go to localhost:3000/graphql
in your browser.
Resolver ant Its Arguments
For our GraphQL servers to respond to our queries, schema
needs to have resolver functions for all fields. Resolver cannot be included inside the GraphQL schema
, they must be added separately.
Inside schema.js
file, define another field inside typeDefs
.
const typeDefs = ` type Query { name: String! alias: String // new field } `
The difference between String!
and String
is that String
returns null
for an empty field. But String!
will give you an error.
We now need to write a a resolver for the alias
field. A resolver takes in four arguments:
-
root
returns the result of the query from the parent value. -
args
takes in arguments. -
context
is used to share the same object with each resolver method. -
info
is used to get the information about theGraphQL
.
Inside typeDefs
, pass in an argument to alias
like this:
const typeDefs = ` type Query { name: String! alias(heroName: String!): String! } `
Go to resolvers.js
file, and write a resolver for alias
:
export const resolvers = { Query: { name (root, args, context, info) { return 'Rajat S'; }, alias(root, {heroName}, context, info) { return heroName; } }, };
Running a query for alias
in the GraphiQL
, you will get the output as:
The context
can be used to provide some kind of authentication information. Inside the app.js
file, add a context
inside the app.use
method.
app.use('/graphql', graphqlHTTP({
graphiql: true,
schema,
context: {
userId: 1
}
}));
To see if this works, log out the context
inside the resolvers.js
file:
export const resolvers = {
Query: {
name (root, args, context, info) {
return 'Clark Kent';
},
alias (root, {heroName}, context, info) {
console.log (context);
return heroName;
},
},
};
Refresh the GraphiQL page, and you will get the {userId: 1}
printed in the terminal.
Replace the context
inside the console.log()
with info
. You will get this inside the terminal.
Fetch all records from Array
Queries in GraphQL are analogous to REST’s GET
. Queries allow us to ask the server for the data we need. But unlike Rest, we can ask exactly what we need from the server.
Inside the schema.js
file, re-write the typeDefs
like this:
const typeDefs = ` type Hero { _id: ID name: String! alias: String! } type Query { allHero: [Hero] } `;
Here I have create a new type called Hero
which has three fields:
-
_id
with the field type ofID
. -
name
with the field type ofString!
. -
alias
with the field type ofString!
.
I am then using this Hero
type inside Query
. Since I want my query to return an array
, the Hero
is wrapped inside a []
.
That’s it. Hope this post helped you learn about about writing GraphQL APIs on Node.js with MongoDB, and feel free to share your feedback and ideas.
GraphQL with Bit
Bit is an OSS platform that helps you turn your GraphQL APIs into components which can be used and developed right from the user’s own projects. Check out these example components or click below to learn more.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK