How to Integrate the latest graphql-shield with my @apollo/server

356 views Asked by At
import * as dotenv from "dotenv";
import mongoose from "mongoose";
import typeDefs from "./graphql/typeDefs.js";
import resolvers from "./graphql/resolvers.js";

import { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import express from "express";
import http from "http";
import pkg from "body-parser";
import cors from "cors";
import { applyMiddleware } from "graphql-middleware";
import { shield } from "graphql-shield";
dotenv.config();
const { json } = pkg;
const MONGODB = process.env.MONGODB;

const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});

await mongoose.connect(MONGODB, {
  useNewUrlParser: true,
});

await server.start();

app.use(
  "/graphql",
  cors({
    origin: ["https://studio.apollographql.com", process.env.FRONTEND_DEV_URL],
  }),
  json(),
  expressMiddleware(server, {
    context: ({ req }) => ({
      token: req.headers.authorization || "",
    }),
  })
);

await new Promise((resolve) =>
  httpServer.listen({ port: process.env.PORT || 4000 }, resolve)
);
console.log(` Server ready `);

package.json:

  "dependencies": {
    "@apollo/server": "^4.7.1",
    "bcrypt": "^5.1.0",
    "body-parser": "^1.20.2",
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "graphql": "^16.6.0",
    "graphql-middleware": "^6.1.34",
    "graphql-shield": "^7.6.5",
    "graphql-tag": "^2.12.6",
    "mongoose": "^7.0.4"
  }

The problem I have is that the official documentation for the graphql-shield is limited and It says I need to apply a middleware and pass my "Schema" and "server"

But as you can see in my code I do not have any Schema and it is automatically being generated by ApolloServer.

My Question: How to implement graphql-shield so I can start to define rules and limit access to queries and mutations or is there a better alternative?

official documentation

1

There are 1 answers

1
Medet Tleukabiluly On BEST ANSWER

You need to pass schema to Apollo, you can create schema by using buildSchema from graphql

Here's a simple pseudo code, its just example

import { buildSchema} from 'graphql'

const schema = buildSchema({
  typeDefs,
  resolvers
})
const permissions = shield({
  Query: {
    frontPage: not(isAuthenticated),
    fruits: and(isAuthenticated, or(isAdmin, isEditor)),
    customers: and(isAuthenticated, isAdmin),
  },
  Mutation: {
    addFruitToBasket: isAuthenticated,
  },
  Fruit: isAuthenticated,
  Customer: isAdmin,
})
const securedSchema = applyMiddleware(schema, permissions)

const server = new ApolloServer({
    schema: securedSchema
})
...