Working with Apollo GraphQl
Tags: graphql, javascript, beginners, webdev
Published: 2022-09-26 13:46:12

GraphQL is a query language and a set of tools that operate over a single endpoint. Unlike REST API, which exposes multiple endpoints.

_There are numerous advantages to using GraphQl over RestApi.
One of the many benefits of GraphQL is that it eliminates the problem of over- or under-fetching by only returning the exact and specific data in a single request._

This blog will show you how to create a simple Pet Application with this query language. 

###### Let's dive in
![dive](https://media.giphy.com/media/SiKqNZqksVYWmQEMjd/giphy.gif)

---

###  Project Setup
Create new project file and cd into it. Initiate `npm init` command to create a Node. js project.

> npm init && npm install graphql uuid apollo-server && touch index.js

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4nuzk7o9pzzk3voz2ck.png)

---

We will not connect to a database; instead, we will use a mock database. 

In your `index.js` import the packages installed earlier
```javascript
const { ApolloServer, gql } = require('apollo-server'); 
const { v4: uuidv4 } = require('uuid');
```

⏭️ Following that, we create our `Type definition`

```javascript
// Defining the types of the data that will be used in the application. 
const defTypes = `
    type Pet{
    id: ID! # ! means Can't return null
    name:String,
    age: Int
    }

    type Query{ // Query is a reserved word in GraphQL
        pets: [Pet]
        pet(id:ID!):Pet!
    }

    type Mutation{
      addPet(name: String!, age: Int!): Pet!
      updatePet(id: ID!, name: String!, age: Int!): Pet!
      deletePet(id: ID!): Pet!
    }
`;
```
GraphQL server uses a schema to describe the shape of your available data. This schema defines a hierarchy of types with fields that are populated from your back-end data stores

The `query` type is used for data retrieval operations, while the `mutation` type is used for data creation or modification operations. 

---

⏭️ Next, let's make our dummy data, which will be an array of objects. 
```javascript

const Pet = [
  {
    id: '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed',
    name: 'Dog',
    age: 2,
  },
  {
    id: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
    name: 'Cat',
    age: 3,
  },
];
```

---

⏭️  Next, we create resolvers
```javascript
// Create Resolvers
const resolvers = {
  Query: {
    pets: () => Pet,
    //query a single pet
    pet: (parent, args) => {
      return Pet.find((pet) => pet.id === args.id);
    },
  },
  Mutation: {
    addPet: (parent, args) => {
      const pet = { id: uuidv4(), name: args.name, age: args.age };
      Pet.push(pet);
      return pet;
    },
    deletePet: (parent, args) => {
      const pet = Pet.find((pet) => pet.id === args.id);
      Pet = Pet.filter((pet) => pet.id !== args.id);
      return pet;
    },

    updatePet: (parent, args) => {
      const pet = Pet.find((pet) => pet.id === args.id);
      pet.name = args.name;
      pet.age = args.age;
      return pet;
    },
  },
};
```
> A resolver is a function that's responsible for populating the data for a single field in your schema. 

Next, we create an Apollo Server
```javascript
// Create Apollo Server
const server = new ApolloServer({
  typeDefs: gql(defTypes),
  resolvers,
});
```

---

⏭️  Lastly we start a server
```javascript
const port = process.env.PORT || 4001;

// Start Server
server.listen(port).then(({ url }) => {
  console.log(`Server started at ${url}`);
});
```

---

##### Your `index.js` file should look like this

```javascript

const { ApolloServer, gql } = require('apollo-server');
const { v4: uuidv4 } = require('uuid');

const defTypes = `
    type Pet{
    id: ID! 
    name:String,
    age: Int
    }

    type Query{
        pets: [Pet]
        pet(id:ID!):Pet!
    }

    type Mutation{
      addPet(name: String!, age: Int!): Pet!

      updatePet(id: ID!, name: String!, age: Int!): Pet!

      deletePet(id: ID!): Pet!
    }
`;

// Create Dummy Data

const Pet = [
  {
    id: '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed',
    name: 'Dog',
    age: 2,
  },
  {
    id: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
    name: 'Cat',
    age: 3,
  },
];

// Create Resolvers
const resolvers = {
  Query: {
    pets: () => Pet,
    //query a single pet
    pet: (parent, args) => {
      return Pet.find((pet) => pet.id === args.id);
    },
  },
  Mutation: {
    addPet: (parent, args) => {
      const pet = { id: uuidv4(), name: args.name, age: args.age };
      Pet.push(pet);
      return pet;
    },
    deletePet: (parent, args) => {
      const pet = Pet.find((pet) => pet.id === args.id);
      Pet = Pet.filter((pet) => pet.id !== args.id);
      return pet;
    },

    updatePet: (parent, args) => {
      const pet = Pet.find((pet) => pet.id === args.id);
      pet.name = args.name;
      pet.age = args.age;
      return pet;
    },
  },
};

// Create Apollo Server
const server = new ApolloServer({
  typeDefs: gql(defTypes),
  resolvers,
});

const port = process.env.PORT || 4001;

// Start Server
server.listen(port).then(({ url }) => {
  console.log(`🏹🏹🏹Server started at ${url}`);
});

```

---

#### Let us start our server. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehmvc5vlajsmht9ihvqo.png)

Visit the url http://localhost:4000 and click on the `Query your server` button

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flbcmh28jyvkxskhuhf5.png)


---

When using GraphQL, consider your query as a `GET` request and your mutations as `PUT`, `DELETE`, or `POST` requests. Use the following command to run a query. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ub27f2ggyo1hwjqnm6l8.png)

Here's one of Apollo Server's best features.
We can only fetch what we need, no more or less. In my case, I only fetched the pets' IDs. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3iktxiftvebxqwhb0ie.png)

---

##### Let's retrieve a single pet using the `id`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f6pwxg5l7ohagllsa3f.png)

Again, we could narrow down the information we want from the query. In my case I removed the `id` 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2atq5phrjkm8jmwl9j05.png)

---

##### Let's create new pet using the 'addPet' mutation. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ozkijm8f5y9vvesuiuvv.png)

Note: The id is derived from the 'uuid' package that we installed. 

#### Update pet information

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jwnnxkkks1obdq0nyqqr.png)


#### Use postman
You can always use Postman or any other API testing software of your choice to make queries. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kn7q011din3i0lynux3z.PNG)

---

### Conclusion
I hope this article was helpful in getting started with Apollo-graphql.

The official documentation contains more information on performance, security, deployment, and monitoring. 

---

#### Source
[Apollo Docs](https://www.apollographql.com/docs/apollo-server/)
[UUID](https://www.npmjs.com/package/uuid)