Part 3:- API using GraphQL and Node.js

Kautilya Tripathi
Programming Society Gazette
6 min readDec 28, 2018

This is Article 3 for this series. You can find first article here and second article here.

About this Article

In this article you will be able to do the following things:-

  • Create an Auth based system.
  • Use JWT to verify the tokens
  • CRUD(Create Read Update Delete) operations for Todo using GraphQL
  • Write tests for it.

Creating a Auth based system

We need to have a system where users can create a todo only when they authenticate themselves as real user. For example, if we don’t authenticate our routes, anyone can create a todo and spammers can spam the database. Also we need to keep track of todo for a particular user. Including them and many other reasons we need to create an Auth based system. So let’s create a folder inside src called as middleware and then create 2 files inside it:-

  • auth.ts
  • index.ts

Inside src/middleware/auth.ts copy this :

auth middleware to authenticate user

Explanation:-

  • Line 1–6:- We require necessary modules for this file.
  • Line 16:- We are exporting a function to check whether a user is authenticated or not. This functions takes an argument which context which is generally a form of request.
  • Line 17:- This function is returning a promise.
  • Line 18–23:- Now as said earlier context is in form of request so it will contain headers, now we will check if any token is passed in x-access-token header. This is a custom header that we will use to pass our JWT token when making a GraphQL request to CRUD operation on a Todo. If token is not present in header we reject our promise with a newresponse that we created in response.ts.
  • Line 26–30:- You can check here how a JWT works. So if any modification is made to our token then it will reject the with a new response.
  • Line 32–48:- If token is not tampered with then we recieve a decoded data. That decode data contains id of user. We then find that user with that id and return it. If no user is found we reject with a response.
  • Line 43–44:- We resolve the promise by passing it to completeRequest and gets back another promise but this promise has response in form we want. We then return the value.

After 2 articles you might have idea what we are going to write in src/middleware/index.ts. You may have already written it 😄, but let’s be sure and copy this code.

export * from "./auth";

Now lets create our Schema for Todo for our mongoose model. Create a file inside schemas named todoSchema.ts and copy this inside

src/schemas/todoSchema.ts

A mongoose schema for Todo model

We already understood how to make a schema when we created userSchema. Here is just one new thing on line 25–28:- We need to reference the todo that is created to the user who created it. So postedBy will contain _id of user who will create that todo. Line 29–31 will store the name of the user.

Also update your src/schemas/index.ts and add

export * from "./todoSchema";

Now we will create functions for CRUD operations on a todo. So create file todo.ts inside routes folder and copy this inside

src/routes/todo.ts

CRUD operation on a TODO

You might now have idea what we are doing. We have 4 functions.

  • addTodo :- This creates a new todo.
  • getAlltodosForUser :- This returns all todos for an authenticated user.
  • update :- This updates a particular Todo.
  • deleteTodo :- This deletes a particular todo.

All Functions are authenticated. That is, only authenticated user can make request to perform CRUD operation.

Now lets create a graphQL schema for our Todo. Create a file todographqlSchema.ts inside schemas folder and copy this inside

src/schemas/todographqlSchema.ts

This is graphQL schema for our Todo

You might have idea about it, as it is somewhat similar to userLoginSchema.ts and userRegisterSchema.ts for graphQL. Also we need to export this file so paste this line inside

src/schemas/index.ts

export * from "./todographqlSchema";

Now we need to finally add queries and mutation inside our graphql.ts. Like we did for loginUser and registerUser. So copy and replace your old code with this inside

src/schemas/graphql.ts

Now lets write tests for our code changes. First we need to create 2 new files inside our test folder.

  • profileQueries.ts
  • todoQueries.ts

Inside src/test/profileQueries.ts copy this code

Profile queries for our test file.

Also copy this to src/test/todoQueries.ts

We need to update our user-test.spec.ts file. This file is very big, so open the link given below and copy the file into your src/test/user-test.spec.ts

Lets run our test by running npm run build && npm run coverage. Make sure your MongoDB is up and running. You will get this output.

Still 💯 code coverage 😉

Accessing the API

First check your mongoDB server is up and running. Then start your server by running the following command

npm start

Now to access the API of application open your GraphQL-Playground and enter url http://localhost:3000/graphql

Creating a Todo

Enter Query

mutation addTodo($input: todoInput) {
addTodo(input: $input) {
code
message
data {
success
todo {
id
postedByid
description
updatedAt
createdAt
name
}
}
}
}

and then query variable

{
"input": {
"title": "This is a test todo",
"description": "Lets see if this works"
}
}

Important:- You need to set HTTP HEADERS. You can get this token with the use of login API.

query loginUser($input: UserInputLogin) {
loginUser(input: $input) {
data {
token
}
}
}

and then query variable

{
"input": {
"username": "knrt10",
"password": "test"
}
}

From this response copy the token and then copy this code to your HTTP HEADERS

{
"x-access-token": "your access token from login API"
}

Then hit play button, you will get response like this. Try removing the token or changing token to something else and see the response.

creating a Todo

Updating a Todo

Enter Query

mutation updateTodo($input: todoInputUpdate) {
updateTodo(input: $input) {
code
message
data {
success
todo {
id
postedByid
description
updatedAt
createdAt
name
title
}
}
}
}

and then query variable. You can get the id from the todo you created before.

{
"input": {
"id": "id of your todo you created before",
"title": "Second check?",
"description": "Yaaho."
}
}

You also need to set header like above. After that when you hit play button you will get this response

updating a Todo

Getting all Todo

Enter Query

query todoUsers {
todoUsers{
code
message
data {
success
todos {
title
description
id
}
}
}
}

and then set HTTP HEADERS like above API.

{
"x-access-token": "Your access token"
}

After that when you hit play button you will get this response

All todos for users

Deleting a Todo

Enter Query

mutation deleteTodo($id: String) {
deleteTodo(id: $id) {
code
message
data {
success
}
}
}

and then query variable. You can get the id from the todo you created before.

{
"id": "5c25156f70d37365ede03609"
}

You also need to set header like above. After that when you hit play button you will get this response

deleting a Todo

Conclusion

That is for this part. In this part you learnt following things:-

  • How to write Schema for GraphQL.
  • How to create Schema for Todo and link it with a User
  • Perform CRUD operation on a Todo using GraphQL.
  • How to write clean code.
  • How maintain 💯 code coverage 😉.
  • You can see it took 33 tests to run in about 804ms. Which is less than a second. It shows how fast and precise our code is.

Code for this series

Code is open sourced on Github under MIT license. Feel free to use it as reference if you are stuck anywhere.

Support

I wrote this series of articles by using my free time. A little motivation and support helps me a lot. If you like this nifty hack you can support me by doing any (or all 😉 ) of the following:

  • Follow me on Github for more such projects.
  • ⭐️ Star it on Github and make it trend so that other people can know about my project.
  • 👏 Clap for this series of articles on Medium.
  • Tweet about it.
  • Share this on Facebook.

--

--

Kautilya Tripathi
Programming Society Gazette

Now writing blogs at https://knrt10.netlify.app/. CKA | OSS ❤️ | Cloud Infrastructure Engineer @kinvolk.io