DEV Community

Tanisha G
Tanisha G

Posted on • Edited on

Getting Started with GraphQL - Nodejs

Image description

What is GraphQL
As per the documentation, "GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools."

But why GraphQL?
Imagine a scenario where the client needs user data but only a username list should be the output. The next one is where the client needs only the user's phone number and the requirement list goes on. Now in the situations mentioned above would you like to write different APIs or send the whole user's data (unnecessary/extra data) over network calls?

This is where GraphQL comes into the picture by using GraphQL queries you can do db actions/queries and return the output directly

Now let's dive into the implementation part, I am going to use the Apollo server to set up Graphql

npm i @apollo/server body-parser express axios
Enter fullscreen mode Exit fullscreen mode

I have set up async startServer function which includes declaring and starting the server, and app.use indicates that any query for the URL /graphql is going to be handled by the server(Apollo)

const server = require("express")
const bodyParser = require("body-parser")
const { ApolloServer} = require("@apollo/server")
const axios = require("axios")
const { expressMiddleware } = require("@apollo/server/express4")
const cors = require("cors")
var app = server()
const startServer = async () => {
 app.use(cors())
 app.use(bodyParser.json())
 const server = new ApolloServer({})
 await server.start()
 app.use(
    "/graphql",
    expressMiddleware(server)
  )
  app.listen(8000, () => {
    console.log("port started on 8000")
  })
}
startServer()
Enter fullscreen mode Exit fullscreen mode

but the Apollo server has certain restrictions where typeDefs and resolvers are compulsory for the server to start. Now let's see what are typeDefs and resolvers

typeDefs are nothing but schema along with type declarations
Example

    type Post{
      id:ID (ID denotes id field can be of type anything)
      title:String! (! Dentos that field can not be null )
      body:String 
    }
Enter fullscreen mode Exit fullscreen mode

resolvers are the ones that give out the result for the queries made.

Let's take up a dummy example for a deeper understanding, user and todo are two different schemas where each user can have multiple todos, and every todo is linked to a particular user by userId.Time to declare some typeDefs.

  const server = new ApolloServer({
 typeDefs: `
    type User{
      name: String!
    }
    type Todo{
      id: ID!
      title: String!
    }
  type Query{
    getTodos:[Todo]
    getUsers:[User]
  }`,
 resolvers:{
 Query: {
   getTodos: async () => (await 
   axios.get("https://jsonplaceholder.typicode.com/todos")).data,
   getUsers: async () => (await 
   axios.get("https://jsonplaceholder.typicode.com/users")).data,
}
})
Enter fullscreen mode Exit fullscreen mode

type Query indicates the query function name and the data return format, so now in the resolvers also Query should be declared and the action to take place inside the function being called should be written.

getTodos is going to fetch all the todo lists in the array format and getUsers is going to fetch all the users in array format as declared in type Query.

Run your server on http://localhost:8000/graphql below mentioned UI will be given by Apollo only,in getTodos query I have mentioned the fields that I want to be in the output but you cannot send any random field, the field being requested should be declared in the schema:

Image description

getUsers:
Image description

Now let's make the query a little more complex

I want to get all the todos along with the user name who has created it
change the schema and resolvers accordingly

 type Todo{
      id:ID!
      title:String!
      user:User
      userId:String!
  }
Enter fullscreen mode Exit fullscreen mode
resolvers{
 Todo: {
        user: async (todo) => (await axios.get(`https://jsonplaceholder.typicode.com/users/${todo.userId}`)).data
      },
Query:{remains the same}
}

Enter fullscreen mode Exit fullscreen mode

The Todo in the resolvers indicates that whenever there is a query Todo needs to get the user details to whom the todo belongs based on userId meanwhile in the schema I have added a user field that will hold the User details which refers to the User schema which is already declared.

Image description

Challenege

Write a function to fetch only particular todo based on the id field. Let me know the query and resolver functions in the comments below.

Conclusion

As we saw what is graphql, why there is a need for it, and a simple example of graphql query in the upcoming blog I will be explaining about mutations i.e. updation/deletion/creation.

Image description

Top comments (0)