Graphql custom route

default discord avatar
guladima
7 months ago
1 2

Is it possible to change the route generation mechanism for graphql? I don't want my graphql url to start with /api.

function initPlayground(ctx: Payload): void {
if ((!ctx.config.graphQL.disable && !ctx.config.graphQL.disablePlaygroundInProduction && process.env.NODE_ENV === 'production') || process.env.NODE_ENV !== 'production') {
ctx.router.get(ctx.config.routes.graphQLPlayground, graphQLPlayground({
endpoint: `${ctx.config.routes.api}${ctx.config.routes.graphQL}`,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore ISettings interface has all properties required for some reason
settings: {
'request.credentials': 'include',
},
}));
}
}

  • default discord avatar
    guladima
    7 months ago

    Finally i solve my problem.

    Here's my working solution:

    server.ts

    import express, { NextFunction, Response } from "express";
    import payload from "payload";
    import graphQLPlayground from "graphql-playground-middleware-express";
    import registerSchema from "payload/dist/graphql/registerSchema";
    import identifyAPI from "payload/dist/express/middleware/identifyAPI";
    import graphQLHandler from "payload/dist/graphql/graphQLHandler";
    import { PayloadRequest } from "payload/types";
    
    require("dotenv").config();
    const app = express();
    
    const start = async () => {
      await payload.init({
        secret: process.env.PAYLOAD_SECRET,
        mongoURL: process.env.MONGODB_URI,
        express: app,
        onInit: async () => {
          payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);
          payload.logger.info(`Payload API URL: ${payload.getAPIURL()}`);
        },
      });
    
      app.use(
        payload.config.routes.graphQL,
        (req, res, next) => {
          if (req.method === "OPTIONS") {
            res.sendStatus(204);
          } else {
            next();
          }
        },
        (
          req: PayloadRequest & { payload: { schemaRegistered?: boolean } },
          _res: Response,
          next: NextFunction
        ) => {
          if (!req.payload.schemaRegistered) {
            registerSchema(req.payload);
            req.payload.schemaRegistered = true;
          }
    
          next();
        },
        identifyAPI("GraphQL"),
        (req: PayloadRequest, res: Response) => graphQLHandler(req, res)(req, res)
      );
    
      app.get(
        payload.config.routes.graphQLPlayground,
        graphQLPlayground({
          endpoint: payload.config.routes.graphQL,
          settings: {
            "request.credentials": "include",
          },
        })
      );
    
      app.listen(3000);
    };
    
    start();

    payload.config.ts

    routes: {
      admin: "/admin",
      api: "/api",
      graphQL: "/graphql",
      graphQLPlayground: "/graphql-playground",
    },
    graphQL: {
      disable: true,
      schemaOutputFile: path.resolve(__dirname, "generated-schema.graphql"),
    },
  • discord user avatar
    DanRibbens
    Payload Team
    7 months ago

    That isn't currently configurable directly. I haven't seen this asked before, but if this is a common thing we could consider how it might be done in the config.

    Alternatively, it may be possible to disable Payload's own graphQL using graphQL.disable: true in your config and set it up separately in your app by importing payload's graphql handler and adding it to your express router under your own path.

    Payload sets up routes for the playground and graphql endpoints here:

    payload/src/initHTTP.ts

    Lines 56 to 70 in 4a49640

    if (!payload.config.graphQL.disable) {
    payload.router.use(
    payload.config.routes.graphQL,
    (req, res, next): void => {
    if (req.method === 'OPTIONS') {
    res.sendStatus(204);
    } else {
    next();
    }
    },
    identifyAPI('GraphQL'),
    (req: PayloadRequest, res: Response) => graphQLHandler(req, res)(req, res),
    );
    initGraphQLPlayground(payload);
    }

    Disabling graphql will also skip registering of the schema, which you'll want to call also. I believe it could be done onInit in which you could pass it payload instead of this.

    payload/src/payload.ts

    Lines 194 to 196 in 4a49640

    if (!this.config.graphQL.disable) {
    registerSchema(this);
    }

    Since we don't export some of these files directly, you'll have to import them from 'payload/dist'.

    I haven't tried to do this and honestly, it probably isn't worth the effort unless this is a hard requirement for your project.

    I hope this helps, cheers!

Open the post
Continue the discussion in GitHub
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.