GraphQL

The Backend

Create the server

  1. npm init

  2. npm i express

  3. Create server.js to spin up the server and listen in any post (here 4000)

const express = require('express');

const app = express();

app.listen('4000', ()=> console.log("listening at  4000"))

  1. node server.js : Outputs Listening at 4000

Install graphQL

  1. npm install express express-graphql graphql --save

  2. Update server.js

var express = require("express")

var { graphqlHTTP } = require("express-graphql")

var { buildSchema } = require("graphql")


const schema = buildSchema(`

    type Query {

        posts: String

    }

`)

var app = express()

app.use(

  "/graphql",

  graphqlHTTP({

    schema: schema,

    graphiql: true,

  })

)

app.listen(4000)

console.log("Running a GraphQL API server at http://localhost:4000/graphql")


  1. For now we can have “posts” as our schema. There is no data yet so we cannot make any queries

  2. “rootValue” needs to be updated for the value of the /posts response. We will hardcode some values for now

var express = require("express")

var { graphqlHTTP } = require("express-graphql")

var { buildSchema } = require("graphql")


const schema = buildSchema(`

    type Query {

        posts: String

    }

`)


const value = {

    posts: () => {

        return "Loreum Impusm"

    }

}

var app = express()

app.use(

  "/graphql",

  graphqlHTTP({

    schema: schema,

    rootValue: value,

    graphiql: true,

  })

)

app.listen(4000)

console.log("Running a GraphQL API server at http://localhost:4000/graphql")

O/p:



Types

Posts cannot be String! Let us make it as an Array of Strings

So instead of String, we update it to [String]


By default, every type is nullable - it's legitimate to return null as any of the scalar types. Use an exclamation point to indicate a type cannot be nullable, so String! is a non-nullable string.
Ex: userID: Int!



To have an even more complex types, we can have “types” just like how we already have “Query” type previously

const schema = buildSchema(`

    type Comment {

        body: String

    }

    type Query {

        posts: String,

        comments: [Comment]

    }

`)

const value = {

    posts: () => {

        return "Loreum Impusm"

    },

    comments: () => {

        return [{body: "MongoDB"}, {body: "Express"}, {body: "GraphQL"}, {body: "Fancy Tech Stack!"}]

    }

}


Update the query to request “body” key inside comments



Updating the types and hardcoded data to match real time scenario:

const schema = buildSchema(`

    type Comment {

        id: Int!,

        postId: Int!,

        body: String,

    }

    type Post {

        userId: Int!,

        id: Int!,

        title: String,

        body: String

    }

    type Query {

        posts: [Post],

        comments: [Comment]

    }

`)

const value = {

    posts: () => {

        return [{

                userId: 1,

                id: 9,

                title: "nesciunt iure omnis dolorem tempora et accusantium",

                body: "consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam aut nobis\net est aut quod aut provident voluptas autem voluptas"

              },

              {

                userId: 1,

                id: 10,

                title: "optio molestias id quia eum",

                body: "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error"

              }]

    },

    comments: () => {

        return [

            {body: "MongoDB", postId: 1},

            {body: "Express", postId: 1},

            {body: "GraphQL", postId: 2},

            {body: "Fancy Tech Stack!", postId: 3}

        ]

    }

}


Now update the Query accordingly:


PASSING THE ARGUMENTS

So far, the resolver functions took no arguments/queries

Scenario: Get  “comments” with postId sent as argument/query

type Query {

        posts: [Post],

        comments(postId: Int!): [Comment]

    }


We can access the “postId” in the rootValue by using “args” property. Ex: args.postId in this case.

OR

Using Object Destructuring in ES6, we can use { postId }


comments: ({postId}) => {

        let posts = [

            {body: "MongoDB", postId: 1},

            {body: "Express", postId: 1},

            {body: "GraphQL", postId: 2},

            {body: "Fancy Tech Stack!", postId: 3}

        ]

        return posts.filter(p => p.postId === postId)

    }


OBJECT TYPES

type Comment {

        id: Int!,

        postId: Int!,

        body: String,

    }

type Query {

        posts: [Post],

        comments(postId: Int!): [Comment]

    }


Instead of a root-level resolver for the [Comment] type, we can instead use an ES6 class, where the resolvers are instance methods.




Comments

Popular posts from this blog

Inside the JavaScript Memory Box: Visualizing Variables, References, and Copies

React & State Management: All Concepts

React: Communication between components