/go-gqlmanage

Fully working GraphQL API written in golang with MongoDB. Features include - resolvers, dataloaders, subscriptions, auth, middleware, filter, redis pub/sub etc.

Primary LanguageGoMIT LicenseMIT

GraphQL API Server with MongoDB

Introduction

Learning gqlgen to build full GraphQL servers with MongoDB. The following project is built to manage multiple devices in multiple rooms. This GraphQL API is designed to be secure and requires the user to login to manage devices. A React Frontend is being built to use this API.

The following Golang Project uses:

Instructions

Rename .env-example to .env and setup variables

# MongoDB server config
MONGODB_URL=mongodb://localhost/
MONGODB_DATABASE=gqlmanage

# Server Port
PORT=8000
CORS=http://localhost:8000

# JWT Token Settings
JWT_SECRET=my_jwt_secret
JWT_ISSUER=my_issuer

Need to insert first user to access API (TODO)

Run server
go run ./main.go
# OR
go run github.com/scorpionknifes/gqlmanage

Notes

Resolvers

Custom resolvers for devices and rooms are created to allow recursive and nested GraphQL calls.

Example of a recursive query.

{
  rooms{
    devices{
      room{
        devices{
         ... 
        }
      }
    }
  }
}
Authentication

Login with username and password to get JWT Token to access other routes. JWT Token has an expire time of 7 days.

mutation login{
  login(input:{
    username: "username"
    password: "password"
  }){
    authToken{
      accessToken
    }
  }
}

Example result getting JWT token

{
  "data": {
    "login": {
      "authToken": {
        "accessToken": "JWT_TOKEN_HERE"
      }
    }
  }
}

Use JWT token to authenticate. Add Authorization Bearer token in Http Header

{
  "Authorization": "Bearer JWT_TOKEN_HERE"
}
Dataloader

Read Here for more info about dataloader in gqlgen.

Dataloader solves repeated queries. The dataloader is used in custom resolver for devices.

Example of repeated queries - room needs to be called multiple times for each device that exist

{
  devices{
    room{
      ...
    } 
  }
}
Subscriptions (with Redis)

Read Subscription with Redis

Read Passing token using Subscription

Websocket subscription is secured with jwt by passing the token through "graphql-ws" header. A different jwt extract method is used.

Redis pub/sub for running multiple instances.

Example of using a jwt token using Apollo Client in ReactJS

const subscriptionClient = new SubscriptionClient(
    "ws://localhost:8000/query",
    {
        reconnect: true,
    },
    null,
    [ "graphql-ws", 'JWT TOKEN' ])

const wsLink = new WebSocketLink(subscriptionClient);