GraphQL with NodeJs and MongoDB
Tags: graphql, mongodb, node, graphqlcompose
Published: 2020-12-05 16:23:54

**What is GraphQL - A Query Language for APIs?**

GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data.
GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data.

Most applications today need to fetch data from a server where that data is stored in a database. It's the responsibility of the API to provide an interface to the stored data that fits an application's needs.

GraphQL is often confused with being a database technology. This is a misconception, GraphQL is a *query language* for APIs - not databases. In that sense it's database agnostic and effectively can be used in any context where an API is used.

### **A more efficient Alternative to REST**

[REST](https://en.wikipedia.org/wiki/Representational_state_transfer) has been a popular way to expose data from a server. When the concept of REST was developed, client applications were relatively simple and the development pace wasn't nearly where it is today. REST thus was a good fit for many applications. However, the API landscape has radically
changed over the last couple of years. In particular, three factors have been challenging the way APIs are designed:

##### **1. Increased mobile usage creates the need for efficient data loading**

Increased mobile usage, low-powered devices, and sloppy networks were the initial reasons why Facebook developed GraphQL. GraphQL minimizes the amount of data that needs to be transferred over the network and thus majorly improves applications operating under these conditions.

##### **2. Variety of different frontend frameworks and platforms**

The heterogeneous landscape of frontend frameworks and platforms that run client applications makes it difficult to build and maintain one API that would fit the requirements of all. With GraphQL, each client can access precisely the data it needs.

##### **3. Fast development & expectation for rapid feature development**

Continuous deployment has become a standard for many companies, rapid iterations and frequent product updates are indispensable. With REST APIs, the way data is exposed by the server often needs to be modified to account for specific requirements and design changes on the client-side. This hinders fast development practices and product iterations.

Over the past decade,[REST] (https://en.wikipedia.org/wiki/Representational_state_transfer) has become the standard (yet a fuzzy one) for designing web APIs. It offers some great ideas, such as *stateless servers* and *structured access to resources*. However, REST APIs have shown to be too inflexible to keep up with the rapidly changing requirements of the clients that access them.

GraphQL was developed to cope with the need for more flexibility and efficiency! It solves many of the shortcomings and inefficiencies that developers experience when interacting with REST APIs.

### **Schema & Type System in GraphQL**

GraphQL uses a strong type system to define the capabilities of an API. All the types that are exposed in an API are written down in a *schema* using the GraphQL Schema Definition Language (SDL). This schema serves as the contract between the client and the server to define how a client
can access the data.

Once the schema is defined, the teams working on frontend and backends can do their work without further communication since they both are aware of the definite structure of the data that's sent over the network.

Frontend teams can easily test their applications by mocking the required data structures. Once the server is ready, the switch can be flipped for the client apps to load the data from the actual API.

GraphQL has its own type system that's used to define the *schema* of an API. The syntax for writing schemas is called [Schema Definition
Language](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51)(SDL).

Here is an example of how we can use the SDL to define a simple type called Person:

`type Person { name: String! age: Int!}`

This type has two *fields*, they're called name and age and are
respectively of type String and Int. The ! following the type means that
this field is *required*.

The *schema* is one of the most important concepts when working with a
GraphQL API. It specifies the capabilities of the API and defines how
clients can request the data. It is often seen as a *contract* between
the server and client.

Generally, a schema is simply a collection of GraphQL types. However,
when writing the schema for an API, there are some special *root* types:

`type Query { \... }
type Mutation { \... }
type Subscription { \... }`

**Mutation**

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 write should be
sent explicitly via a mutation.

## **Why do we need GraphQL?**

With traditional REST API calls, we didn't have the ability for the
client to request a customized set of data. In contrast, GraphQL allows
clients to define the structure of the data required, and the same
structure of the data is returned from the server. This prevents
excessively large amounts of data from being returned. However, it also
adds a layer of complexity that may not be applicable for simple APIs.

Moreover, maintaining multiple endpoints is difficult in REST
architecture. When the application grows, the number of endpoints will
increase, resulting in the client needs to ask for data from different
endpoints. GraphQL APIs are more organized by providing structured types
and fields in the schema while using a single API endpoint to request
data.

**What is Graphql-compose?**

Toolkit for generating complex GraphQL schemas in Node.js.
Graphql-compose provides a convenient way to create GraphQL Schema. This schema is completely compatible with
[GraphQL.js](https://github.com/graphql/graphql-js).

graphql-compose -- provides a type registry with a bunch of methods for
programmatic schema construction. It allows not only to extend types but
also to remove fields, interfaces, args. If you want to write your graphql
schema generator -- graphql-compose is a good instrument for you.

-   provides methods for editing GraphQL output/input types (add/remove
    fields/args/interfaces)

-   introduces Resolvers -- the named graphql fieldConfigs, which can be
    used for finding, updating, removing records

-   provides an easy way for creating relations between types via
    Resolvers

-   provides converter from OutputType to InputType

-   provides projection parser from AST

-   provides GraphQL schema language for defining simple types

-   adds additional types Date, JSON

## **Moving to the code**

Let's start developing. First, we will create a new folder and initialize
our package.json file. Then add the following packages with the command
listed below:

`npm init --y
npm i express graphql express-graphql mongoose graphql-compose-mongoose graphql-compose`

our folder structure is like this
![folder structure](https://dev-to-uploads.s3.amazonaws.com/i/8hfczxybzt6jmdec1h9j.png)

Now in the server.js, we will set up a basic express server and will import the graphqlHTTP from express-graphql.
We will also set up /graphql route and will define the graphql middleware and will set the graphql graphqlSchema.
The beauty of the graphql-compose is that it will auto-generate the graphql scheme, mutations, and query for us based on our mongoose schema.

![server.js](https://dev-to-uploads.s3.amazonaws.com/i/i6kg0whudf7v5ee7fwwp.png)


Let's create our mongoose models, we'll be creating a book model and user model
![user.js](https://dev-to-uploads.s3.amazonaws.com/i/as0dtg1fj2tlo3qajq4b.png)

![book.js](https://dev-to-uploads.s3.amazonaws.com/i/oxa28j34edaosodp3wwa.png)

Now it's time to create GraphQL Scheme for the user model, where all the queries and mutations are defined.

![user.js](https://dev-to-uploads.s3.amazonaws.com/i/byz308k36ulckrzfggjo.png)

you can see that the definition of all the resolvers is automatically generated by the graphql-compose-mongoose plugin like `findById`, `findOne`, `createOne`, etc. You can find all the build-in [mongooseResolvers](https://graphql-compose.github.io/docs/plugins/plugin-mongoose.html)

This is how our GraphQL Scheme for `book` looks like
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2r8fb7h8y5ylhztm9y92.png)

and now its time to build our schemas
![index.js](https://dev-to-uploads.s3.amazonaws.com/i/h4e8lm0xfc177gt3mvyj.png)

Once this is done now its time to run our application
`node start src/server.js` and navigate to `http://localhost:5000/graphql`
you can insert the data using the mutations

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vklcdw8f22genwo1wcwl.png)
 To get the data use a query like this
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tt5jz7ie176w92xbwscl.png).
You can find the documentation on the GraphQL playground
Link to source code [link](https://github.com/adityajoshi12/GraphQL-MongoDB.git)