# Using Node.js Express to Quickly Build a GraphQL Server APIs are a way clients and servers communicate with one another. Data is exchanged between them in mutual understanding, and the most efficient specification for doing this has been the REST API. With REST API multiple requests must be sent in order to access and combine data from different endpoints. In addition, developers often have to deal with over-fetching (information downloaded in excess of what the application needs) and under-fetching (not enough information received by the client, which then has to make several requests. But, as time has passed, we have become more accustomed to how we want to use our data on the internet. We now have more clients, including web clients, iOS clients, Android clients, Heroku, and Apple Watch. They all want access to the same fundamental pieces of data, but at different levels of granularity, speed, and performance. This is where Graphql comes in handy. GraphQL allows multiple resource requests in a single query call, which saves time and bandwidth by reducing the number of network round trips to the server. GraphQL is a language that enables you to provide a complete and understandable description of the data in your API. Furthermore it gives clients the power to ask for exactly what they need and nothing more. The project’s website can be found at [http://graphql.org/.](http://graphql.org/) In this tutorial you’ll learn how to setup a GraphQL server with Node.js and Express. We’ll be using the Express middleware _express-graphql_ in our example. Furthermore you’ll learn how to use GraphQL on the client side to send queries and mutations to the server. ## Why GraphQL **Key concepts of the GraphQL** query language are: **GraphQL is declarative**: Query responses are decided by the client rather than the server. A GraphQL query returns exactly what a client asks for and no more. **GraphQL is compositional**: A GraphQL query itself is a hierarchical set of fields. The query is shaped just like the data it returns. It is a natural way for product engineers to describe data requirements. **Product‐centric** **GraphQL is strongly-typed**: A GraphQL query can be ensured to be valid within a GraphQL type system at development time allowing the server to make guarantees about the response. This makes it easier to build high-quality client tools. All the data types (such as Boolean, String, Int, Float, ID, Scalar) supported by the API are specified in the schema in the GraphQL Schema Definition Language (SDL), which helps determine the data that is available and the form in which it exists. This strongly-typed schema makes GraphQL less error-prone and provides additional validation. GraphQL also provides auto-completion for supported IDEs and code editors. ### Fetch Only Requested Data (No Over- or Under-Fetching) With GraphQL, developers can fetch Client‐specified queries exactly what is required. Nothing less, nothing more. The ability to deliver only requested data solves the issues that arise due to **over-fetching** and **under-fetching**. ### Versioning is Not Required In REST architecture, developers create new versions (e.g., api.domain.com/v1/, api.domain.com/v2/) due to changes in resources or the request/response structure of the resources over time. Hence, maintaining versions is a common practice. With GraphQL, there is no need to maintain versions. The resource URL or address remains the same. You can add new fields and deprecate older fields. This approach is intuitive as the client receives a deprecation warning when querying a deprecated field. ### Saves Time and Bandwidth GraphQL allows multiple resource requests in a single query call, which saves time and bandwidth by reducing the number of network round trips to the server. It also helps to prevent waterfall network requests, where you need to resolve dependent resources on previous requests. For example, consider a blog’s homepage where you need to display multiple widgets, such as recent posts, the most popular posts, categories, and featured posts. With REST architecture, displaying these would take at least five requests, while a similar scenario using GraphQL requires just a single GraphQL request. **Hierarchical** **Product‐centric** **Introspective** ## When to Use GraphQL? GraphQL works best for the following scenarios: GraphQL is an excellent solution to a unique problem around building and consuming APIs. When used as designed, it can be an ideal tool for the use cases described below. - Apps for devices such as mobile phones, smartwatches, and IoT devices, where bandwidth usage matters. - Applications where nested data needs to be fetched in a single call. For example, a blog or social networking platform where posts need to be fetched along with nested comments and details about the person commenting. - A composite pattern, where an application retrieves data from multiple, different storage APIs. For example, a dashboard that fetches data from multiple sources such as logging services, backends for consumption stats, and third-party analytics tools to capture end-user interactions. ### Data fetching control GraphQL was designed to allow the client to ask for only the data it needs. While the server might be able to deliver more data to the client for a single request, it would only send the data requested by the client. If you want the client to control the type and amount of data it needs, GraphQL would be ideal for your project. ### Using multiple data sources GraphQL simplifies the task of aggregating data from multiple sources or APIs and then resolving the data to the client in a single API call. On the other hand, API technologies like REST would require multiple HTTP calls to access data from multiple sources. ### Alleviating bandwidth concerns Bandwidth is a problem for small devices like mobile phones, smartwatches, and IoT devices that are not able to handle large amounts of data. Using GraphQL helps minimize this issue. Because GraphQL allows the client to specify what data it needs, the server doesn’t send excess data, which could reduce the app’s performance when bandwidth is limited. ### Rapid prototyping GraphQL exposes a single endpoint that allows you to access multiple resources. In addition, resources are not exposed according to the views that you have inside your app. So, if your UI changes, for example, requiring either more or less data, it doesn’t have an impact or require changes on the server # Setting Up The Project To setup a GraphQL Node.js server let’s start with creating a new project folder: `$ mkdir apollo-graphql-server` Change into that directory and initiate a new _package.json_ file by executing the following NPM command: `$ npm init` To get started with our schema, we'll need a couple packages first: `apollo-server` and `graphql`. Next, we will make sure that NPM packages _graphql_, _express_ and _express-graphql_ are added to the project: `$ npm install graphql express express-graphql —save` - The `graphql` package provides the core logic for parsing and validating GraphQL queries. - The `apollo-server` package provides a full-fledged, spec-compliant GraphQL server with some nice utilities like the `gql` template literal that we'll use in a moment. Furthermore let's some extra files, we will need to implement our Node.js GraphQL server. Create a new `index.js` `resolvers.js` and `typeDefs.js` file in the project directory: ``` 📂 client ┣ 📂 node_modules ┣ .env ┣ index.js ┣ package-lock.json ┣ package.json ┣ resolvers.js ┣ typeDefs.js ``` ### Creating A Basic GraphQL Server With Apollo Express Server Let’s dive in deep to understand the usage of files we create: In the `typeDefs.js` file (short for "type definitions") this It defines the shape of the data and the hierarchy of types with fields that are populated from your back-end data stores. The schema also specifies exactly which queries and mutations are available for clients to execute. How to Define the Schema A GraphQL Schema is at the core of any GraphQL server implementation. It **describes the shape of your data**, defining it with a hierarchy of **types** with fields that are populated from your data source. It also specifies which **queries** and **mutations** are available, so the client knows about the information that can be requested or sent. Schema At its heart, a schema is a collection of **object types** that contain **fields**. Each field has a type of its own. A field's type can be **scalar** (such as an `Int` or a `String`), or it can be _another object type_. For example, the `Track` object type in our schema will have an `author` field of type `Author`. We declare a type using the `type` keyword, followed by the name of the type (PascalCase is best practice), then opening brackets to hold its contained fields: ```javascript const { gql } = require("apollo-server-express"); const typeDefs = gql` type Query { welcome: String } `; module.exports = {typeDefs}; ``` Now in `schema.js`, let's obtain the `gql` template literal from `apollo-server`: What is this `gql` thing we're importing? It's a tagged template literal, used for wrapping GraphQL strings like the schema definition we're about to write. This converts GraphQL strings into the format that Apollo libraries expect when working with operations and schemas, and it also enables syntax highlighting. We have to import the **tag function** `gql` from **apollo-server** to parse the schema this way: `const {gql} = require('apollo-server');` and then declare a `typeDefs` constant which is an [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of the Graphql code. When a GraphQL server receives a query to process, it generally comes in as a String. This string must be tokenized and parsed into a representation that the machine understands. This representation is called an abstract syntax tree We're still missing one piece though: how to tell the GraphQL server what to retrieve when we query it. Remember, we don't have multiple specific endpoints to target different types like a REST API does. Instead, we define a special `Query` type. The fields of this type are **entry points** into the rest of our schema. These are the top-level fields that our client can query for. For now, we're only interested in fetching our application's welcome message. # H Next, let's declare a `resolvers`. `resolvers`: functions that are called to execute a field and produce a value **→ Resolvers:** A function applied to every _field._ It specifies how that field is connected to the backend and fetches data for that field from a database. Now that we have defined our Schema, we need a way to answer the client requests for that data: the **resolvers**. **A resolver is a function that handles the data for each one of the fields of your schema**. You can send that data to the client by **fetching a back-end database** or a third-party **API**, among others. They have to **match the type definitions of the Schema**. In our case, we just have one type definition, Query, which returns a greeting of type `String`, so we will define a resolver for the `greeting` field, like so ```js const Todo = require('./models/Todo.js') const resolvers = { Query: { welcome: () => { return "Welcome to Refletoring Blog"; } }, }; module.exports = {resolvers}; ``` Next a root resolver is created. A resolver contains the mapping of actions to functions. In our example from above the root resolver contains only one action: message. To keep things easy the assigned functions just returns the string _Hello World!_. Later on you’ll learn how to include multiple actions and assign different resolver functions. In the root resolver we’re connecting the _course_ query action to the _getCourse_ function and the _courses_ query action to the _getCourses_ function. As I explained at the beginning, we will keep this example as simple as possible. But keep in mind that in a real case **here is where you have to make the queries** to the database, external API, or from whichever one you intend to extract the query data. ## Setting up the Apollo Server In our`index.js`, we define and create a new `ApolloServer` object, passing the `Schema` (typeDefs) and `resolvers` as parameters. ``` const express = require("express"); const { ApolloServer } = require("apollo-server-express"); const {typeDefs} = require("./typeDefs") const {resolvers} = require("./resolvers") const app = express() require("dotenv").config(); async function initServer(){ const apolloServer = new ApolloServer({ typeDefs, resolvers }) await apolloServer.start(); apolloServer.applyMiddleware({ app }) app.use((req, res)=> { res.send("Server started successfully") }) } initServer(); app.listen(5000, () => { console.log(` 🚀 Server is running! 🔉 Listening on port 5000 📭 Query at http://localhost:5000 `); }); ``` Ok, let’s examine the above code step by step. First we import our defined type and resolver functionma which now consists of a welcome String and a query actions. we define and create a new `ApolloServer` object, passing the `Schema` (typeDefs) and `resolvers` as parameters. Then calling the `listen` method we start the server on the `port` that we specify in the params. We are done with the initial setup of the project. Now let’s start the project by using the script Now type the URL [http://localhost:5000/graphql](http://localhost:9000/graphql) in your favourite browser. The sandbox to test your endpoint will be opened Let's click _Query your server_ to see our graph in action with Apollo Sandbox # image 00 To write our queries, we'll be using the **Explorer** page in Apollo Sandbox. The Explorer is free to use, and it provides awesome development features like interactive query building, query history, and response hints. This will make building our queries fast and fun. When we arrive in the Sandbox Explorer, it should look something like this: # image -01 The _Operation_ panel in the middle is where we create queries. The Explorer has already filled in a default operation that uses our `tracksForHome` query! You can edit the operation directly or add fields from the _Documentation_ tab (more on this below). The _Operation_ panel in the middle is where we create queries. The Explorer has already filled in a default operation. We can edit the operation directly or add fields. Replace the operation code with this to query for our welcome message. ```gql query ExampleQuery { welcome } ``` At the top of the _Operation_ panel is the button to run our query. Let's click it now and see what happens: # image 01 The _Response_ panel on the right displays our list of track IDs. Sweet! ### Implementing Our Todo Application Next Let's move to creating our Todo Application APIs For Our Todo APIs we will be using a mongodb database to store tasks ## Database First step in this section is will be adding ```js const { gql } = require("apollo-server-express"); const typeDefs = gql` scalar Date type Todo { id: ID title: String detail: String date: Date } type Query { welcome: String getTodos: [Todo] getTodo(id: ID): Todo } type Mutation { addTodo(title: String, detail: String, date: Date): Todo deleteTodo(id: ID): String updateTodo(id: ID, title: String, detail: String, date: Date): Todo } `; module.exports = { typeDefs }; ``` In the above code step by step: First we are declring a Date type, this is a date string, such as `2007-12-03`. Then we defined a type `Todo` that represents a particular todo. For the todo's fields, we'll have: - `id` of type `ID!` - `title` of type `String!` - `detail` of type `String` - `date` of type `Date` we add an exclamation mark after its type, If a field should never be null (non-nullable). Next in our query type we added two new entry point to our query: - `getTodos` of type `[Todo]` : This returns an array of Todos. - `getTodo(id: ID)` of type `Todo` : This takes in `id` as an argument and returns a single Todo. So far, our app has only used one type of GraphQL operation: queries, for retrieving (read-only operations) data from our API. To modify data, we need to use another type of GraphQL operation: **mutations** (write operations). We declare the `Mutation` type using the `type` keyword, then the name `Mutation`. Inside the curly braces, we have our entry points, the fields we'll be using to mutate our data Much like the `Query` type, the `Mutation` type serves as an entry point to our schema. It follows the same syntax as the schema definition language. Here are the mutation we defined: - `addTodo(title: String, detail: String, date: Date)` of type `Todo`: This mutation takes in title, details and date arguments , It is used to create new `Todo` - `updateTodo(id: ID, title: String, detail: String, date: Date)` of type Todo: This mutation needs to know which track to update, so we'll take in an argument `id`. This argument's type is `ID!`, and it's required, so we'll add an exclamation point (`!`) at the end - `deleteTodo(id: ID!)` of type `String`: Then Heading to our `resolver.js` file replacing our code with this: ```js const Todo = require("./models/Todo.js"); const resolvers = { Query: { welcome: () => { return "Welcome to Refletoring Blog"; }, getTodos: async () => { const todos = await Todo.find(); return todos; }, getTodo: async (root, args) => { const todo = await Todo.findById(args.id); return todo; }, }, Mutation: { addTodo: async (root, args) => { const newTodo = new Todo({ title: args.title, detail: args.detail, date: args.date, }); await newTodo.save(); return newTodo; }, deleteTodo: async (root, args) => { await Todo.findByIdAndDelete(args.id); return "Todo Deleted Succefully"; }, updateTodo: async (root, args) => { const { id, title, detail, date } = args; const updatedTodo = {}; if (title != undefined) { updatedTodo.title = title; } if (detail != undefined) { updatedTodo.detail = detail; } if (date != undefined) { updatedTodo.date = date; } const todo = await Todo.findByIdAndUpdate(id, updatedTodo, { new: true }); return todo; }, }, }; module.exports = { resolvers }; ``` In the above code we are: It is a function that queries the requested data from the appropriate data source. ## Setting Up Server Database Next We are goin to connect our mongoDB database to our server, in the `index.js` file ```js const express = require("express"); const { ApolloServer } = require("apollo-server-express"); const {typeDefs} = require("./typeDefs") const {resolvers} = require("./resolvers") const mongoose = require("mongoose"); const app = express() require("dotenv").config(); const MONGO_URI="mongodb+srv://ajibade:beowulfa@nodefirst.owzga.mongodb.net/graphqlDatabase?retryWrites=true&w=majority" mongoose .connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => { console.log(`Db Connected`); }) .catch(err => { console.log(err.message); }); async function initServer(){ const apolloServer = new ApolloServer({ typeDefs, resolvers }) await apolloServer.start(); apolloServer.applyMiddleware({ app }) app.use((req, res)=> { res.send("Server started successfully") }) const PORT = process.env.PORT || 5000; } initServer(); app.listen(5000, () => { console.log(` 🚀 Server is running! 🔉 Listening on port 5000 📭 Query at http://localhost:5000 `); }); ``` In the above code block we introduced mongodb connection setup to our server. This is where all our created Todo tasks will be saved. We are ready to start our server and create some tasks in our Todo also so we can test our APIs. We are done with the initial setup of the project. Now let’s start the project by using the script added in package.json Run the following command inn the terminal ``` node inde.js ``` ## Test APi Our application has been started and ready for testing, head to the graphql emulator, Now type the URL [http://localhost:9000/graphql](http://localhost:9000/graphql) in your favourite browser. The sandbox to test your endpoint will be opened. Replace our _Operation_ panel code with this to query for our welcome message and hit the run button: # image 02 ADD Right now, clicking on the run button have created a new Todo using the information we provided. To get all created to do we can run this query # image 03 Get All The above query we GET all our created todo, and fetch the data of the inputed field you will notic our todo date field not been fetched because we didnt query for it, Include date to the above query, to query for our todo dates. Next we can get one Todo by querying with a Todo `id` # image 04 Get One Using the Todo Id as an argumrnt we can query for just one Todo from our database. Updating a Todo is also a mutation action in the graphql scope To carry out the update mutation of our stored Todo Task run this query in the Operational Panel # image 05 Update Updating our Todo Deleting a Store ## Conclusion Having installed these packages successfully we’re now ready to implement a first GraphQL server