DEV Community

Lakshay
Lakshay

Posted on

Configuring GraphQL for backend

Hello from the Dev cave! 🍻
Hope you are safe and healthy.

This one is about sharing with you all how I configure GraphQL for my backend. It might help someone, or someone might have a better idea and would increase my knowledge.

I also did one about how I configure and consume on frontend and here is a link to that post.

For my setup, I use NodesJS & Apollo Server with MongoDB. You can find its docs and read more about Apollo here.

You need three main things to implement GraphQL -

  1. Something that can understand the GraphQL spec, implement it and handle its requests - something like Apollo server. There are many out there, but I prefer Apollo because I find it simple. As their docs say, Apollo Server is an open-source, spec-compliant GraphQL server that's compatible with any GraphQL client, including Apollo Client. Also, I use Apollo client for my frontend.

  2. Type Definitions - things that define your operations and the shape of data those operations will handle.

  3. Resolvers - functions that assist to resolve (or fulfil) those operations.

Setup

Install the dependencies.

yarn add apollo-server graphql
Enter fullscreen mode Exit fullscreen mode

Once installed, I suggest you to create a folder - something like graphql - in your src directory, just keep things organised. Inside that, you can create your resolvers and type defs.

What I do is, I have a single source for types i.e. typeDefs.js and one folders for resolvers. This folder has respective resolvers as per type defs like users.js, posts.js, etc and all of them being combined in an index file.

Type Definitions

Import the gql tag from apollo-server package.

const { gql } = require('apollo-server');
Enter fullscreen mode Exit fullscreen mode

I use gql tag to defines types. Writing Type Defs is like defining schemas that shape your data. They define the basic structures with fields on which your GraphQL operates.

One key thing to remember about them is, GraphQL follows these schemas strictly. It doesn't care what you do or how you do, all it cares for is how you maintain the shape of the data you are receiving or returning.

Let's write 3 TypeDefs - a user schema, a query (or a request) to get that user and a mutation ( an operation that does something).

  1. A User Schema

    TypeDef User

  2. A Query and Mutation

    
        type Query{
            getUserByUserId(userId: String): User
            getAllUsers: [User]!
        }
    
        type Mutation{
            login(username: String!, password: String!): User!
            register(registerInput: RegisterInput): User!
        }
    
    

Also you can create custom input types to expect an argument in mutations or queries.

input RegisterInput{
        name: String!
        email: String!
        password: String!
}
Enter fullscreen mode Exit fullscreen mode

The ! means that this value is required and cannot be null.

Queries and Mutation (i.e. resolvers)

You can defines your queries and mutations like general async functions. All Apollo GraphQL demands demands is that -

  1. You should wrap these in a JS Object.

  2. Name of each queries and mutation should be same as what you have defined in Type Definitions. Remember, GraphQL is a very strict follower.

  3. All queries should be wrapped in a parent Object with key Query and same for mutations.

  4. The values you return from these resolvers, should have the same shape as you have defined in the Type Defs.

resolvers

You may write different types of queries/mutations in their own files like one for users and one for posts, etc. You can combine them in an index.

const usersResolvers = require('./users');

module.exports = {
    Query: { 
        ...usersResolvers.Query,
    },
    Mutation: {
        ...usersResolvers.Mutation,
    }
}
Enter fullscreen mode Exit fullscreen mode

Once you have your initial template ready, you need to configure the Apollo server instance.

The Apollo server instance

I configure the Apollo server instance with 3 config options -

  1. The Type defs
  2. The Resolvers
  3. Context

Think of context like a middleware which gives you access to the request object. You'll learn more about this when you'll start learning and/or implementing GraphQL.

I use this context, to check for the auth header to confirm whether the request has arrived from a valid source.

Below is the snippet.

Apollo Server config

Once this is done, you can hit your package manager yarn/npm to start and spin this server.

Let me know what you think about this and if you are experienced with GraphQL, I would love to know your suggestions on making my GQL code better.

Any feedback, feel free to comment below or hit me up. Hope I helped someone in some way.

Cheers!

Discussion (0)