3 Ways to Implement Permissions in GraphQL API

3 Ways to Implement Permissions in GraphQL API

Learn how to implement permissions in GraphQL using three different methods: directives, middleware resolvers, and the GraphQL shield library.

Learn how to implement permissions in GraphQL using three different methods: directives, middleware resolvers, and the GraphQL shield library.

Introduction

GraphQL has become the new normal for developing APIs. It has its own advantages and flexibility. One such advantage is that it allows you to implement permissions and granular access control in the API.

Getting granular access control is a big pain in large REST APIs. In GraphQL, you can achieve granularity quite easily.

In this article, we will see different patterns to implement permissions in a GraphQL API.

Basics of access control and permissions

Access control – Checking whether the user is authorized to access the API.

Usually if a user is not logged in but the API endpoint requires a logged in user, the API throws an authentication error.

If the user is logged in but doesn’t have enough permission to perform the operation, the API will throw a forbidden error or an unauthorized error.

Permissions – Permissions is a set of rules that help to make the decision as to whether the user will get access to a particular API.

Let’s check some example use cases for permissions.

Consider the Twitter app:

  • A user can write a Tweet
  • The author who wrote the tweet can delete it
  • Other users can like, retweet, or share the Tweet
  • Other users can report a Tweet
  • Both the author of the Tweet and other users can participate in the comment thread on the Tweet

As you can see, both the author and other users have different levels of permissions, even though the level of authorization is same. They are all authorized as users, but based on activity, they have different rights of access.

Permissions in GraphQL

You can implement permissions in different ways in a GraphQL API. For instance, you can implement permissions through GraphQL directives in the schema or by checking permissions in GraphQL middleware (such as resolvers).

Depth of permissions

In GraphQL, you can go to any depth to implement permissions.

You can do query level permissions, object level permissions, and field level permissions.

Different ways to implement permissions in GraphQL

There are different techniques to implement these permissions: directives, middleware resolvers, and the GraphQL shield library.

We will see all these techniques in our example. Now, let’s build a simple GraphQL server example.

Building a simple GraphQL API

First, create a new npm project:

npm init

Add your express, apollo-server-express and graphql package.

npm i express apollo-server-express

Next, create an index.js file with the sample GraphQL server:

const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');

// Construct a schema, using GraphQL schema language
const typeDefs = gql`
  type Query {
    hello: String
  }
`;

// Provide resolver functions for your schema fields
const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
};

const server = new ApolloServer({ typeDefs, resolvers });
const app = express();
server.applyMiddleware({ app });

app.listen({ port: 4000 }, () =>
  console.log(` Server ready at http://localhost:4000${server.graphqlPath}`)
);

Let’s add nodemon to run the server locally. Nodemon helps to reload the server by watching the files for changes during development:

npm i -D nodemon

Add scripts to run the server in the package.json file:

"scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
},

Let’s start the server in the terminal:

npm run dev

The server will open at the port 4000.

Let’s create few more files and split the code. We’ll use a schema.js file for the GraphQL type definitions:

// schema.js

const { gql } = require("apollo-server-express");
// Construct a schema, using GraphQL schema language
module.exports = gql`
  type Query {
    hello: String
  }
`;

And resolver.js file for the resolvers:

// schema.js

const { gql } = require("apollo-server-express");
// Construct a schema, using GraphQL schema language
module.exports = gql`
  type Query {
    hello: String
  }
`;

Let’s create some data and corresponding queries and resolvers for a simple Tweet application.

The data.js file will be:

// data.js

module.exports = [
  {
    id: 0,
    content: "HTML is a programming language",
    author: "Param",
  },
  {
    id: 1,
    content: "JavaScript programmers are beginners",
    author: "Param",
  },
  {
    id: 2,
    content: "HTML and CSS pages are enough to build a bank project",
    author: "Joshua",
  },
  {
    id: 3,
    content: "React Js can prove earth as flat in 2025",
    author: "Joshua",
  },
];

Now, we will create queries and resolvers to display this Tweet data:

// schema.js

const { gql } = require("apollo-server-express");
// Construct a schema, using GraphQL schema language
module.exports = gql`
  type Query {
    hello: String
    tweets: [Tweet]!
    tweet(id: Int!): Tweet!
  }

  type Tweet {
    id: Int!
    content: String!
    author: String!
  }
`;

Resolvers for the tweets and tweet query:

// resolvers.js

const { ApolloError } = require("apollo-server-express");
const tweets = require("./data");

// Provide resolver functions for your schema fields
module.exports = {
  Query: {
    hello: () => "Hello world!",
    tweets: () => {
      return tweets;
    },
    tweet: (_, { id }) => {
      const tweetId = tweets.findIndex((tweet) => tweet.id === id);
      if (tweetId === -1) return new ApolloError("Tweet not found");
      return tweets[tweetId];
    },
  },
};

We now have the basic GraphQL server ready. Let’s jump into the graphQL permissions through examples.

graphql api database web-development developer

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

A Simple Guide to API Development Tools

APIs can be as simple as 1 endpoint for use by 100s of users or as complex as the AWS APIs with 1000s of endpoints and 100s of thousands of users. Building them can mean spending a couple of hours using a low-code platform or months of work using a multitude of tools. Hosting them can be as simple as using one platform that does everything we need or as complex as setting up and managing ingress control, security, caching, failover, metrics, scaling.

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Tracking a Developer’s Journey From Documentation Visit

Measuring website activity provides only half the story. See how to best track the developer's journey and what funnel stages makes sense for API-first products

How to Market to Developers with Paid Marketing

Selling to developers is hard. How to market to developers efficiently using paid advertising leveraging inbound marketing techniques.