apollo-server-integrations / apollo-server-integration-koa

An integration that lets you run your Apollo GraphQL server as part of an app built with Koa
MIT License
18 stars 3 forks source link

How do I specify a URL path where the default behavior is that all URL path are OK #195

Closed quirkybird closed 10 months ago

quirkybird commented 1 year ago

I see apollo-server-express, the default URL is /graphql, which can also be customized,look like:

.../
app.use(
  '/graphql',
  cors<cors.CorsRequest>(),
  express.json(),
  expressMiddleware(server, {
    context: async ({ req }) => ({ token: req.headers.token }),
  }),
.../
);

I tried the same thing. It didn't work

vcellu commented 10 months ago

Hi, did you resolve this issue?

matthew-gordon commented 10 months ago

@quirkybird @vcellu , you can see a previously closed issue on this topic here https://github.com/apollo-server-integrations/apollo-server-integration-koa/issues/61.

You can try using the @koa/router package:

import koa from 'koa';
import Router from '@koa/router';

const app = new Koa();
const router = new Router();

router.all('/graphql', koaMiddleware(server));

app
  .use(router.routes())
  .use(router.allowedMethods());

Hope this helps!

quirkybird commented 10 months ago

@matthew-gordon thank you!!!!!!!!!

quirkybird commented 10 months ago

I still can't solve this problem, can you give me the full code, like the README, because here it is

  app.use(
    koaMiddleware(server, {
      context: async ({ ctx }) => ({ token: ctx.headers.token }),
    })
  );
matthew-gordon commented 10 months ago

I still can't solve this problem, can you give me the full code, like the README, because here it is

  app.use(
    koaMiddleware(server, {
      context: async ({ ctx }) => ({ token: ctx.headers.token }),
    })
  );

Hi @quirkybird, it looks like you still aren't using the @koa/router package, following is a small snippet. If you still can't get this working I would be happy to take a look at a repo and code that you have to help troubleshoot.

The code snippet you provided is available at the root route / however here is a typescript example

Note: This example is using typescript

import http from "http";
import Koa from "koa";
import bodyParser from "koa-bodyparser";
import cors from "@koa/cors";
import { ApolloServer } from "@apollo/server";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import { koaMiddleware } from "@as-integrations/koa";
import Router from "@koa/router";

// The GraphQL schema
const typeDefs = `#graphql
  type Query {
    hello: String
  }
`;

// A map of functions which return data for the schema.
const resolvers = {
  Query: {
    hello: () => "world",
  },
};

export default async function start() {
  const app = new Koa();
  const httpServer = http.createServer(app.callback());
  const router = new Router();

  // Set up Apollo Server
  const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
  });
  await server.start();

  app.use(cors());
  app.use(bodyParser());

  router.all(
    "/graphql",
    koaMiddleware(server, {
      context: async ({ ctx }) => ({ token: ctx.headers.token }),
    })
  );

  app.use(router.routes())
  app.use(router.allowedMethods());

  await new Promise<void>((resolve) =>
    httpServer.listen({ port: 4000 }, resolve)
  );
  console.log(`🚀 Server ready at http://localhost:4000/graphql`);
}

start()
quirkybird commented 10 months ago

So now we have to use the following code at the end?

app.use(router.routes()) ;
app.use(router.allowedMethods());
quirkybird commented 10 months ago

@matthew-gordon ,I see what you mean, but I configured the router and then I started the server here, which seems to be in a different order, so what does koaMiddleWare() do?

matthew-gordon commented 10 months ago

@matthew-gordon ,I see what you mean, but I configured the router and then I started the server here, which seems to be in a different order, so what does koaMiddleWare() do?

The koaMiddleware is used to translate requests and responses between koa’s native format to the format used by ApolloServer. If you want to see more info about implementation for frameworks, check out the docs for building integrations.

Ultimately the order of the middleware determines how the incoming request is processed, we start the Apollo server first, then mount the koaMiddleware to ensure graphql requests are parsed and translated correctly.

Order might not particularly matter for router configuration if you have any RESTful routes or callback urls configured before server start, the most important thing is to ensure the below is called AFTER your server start however.

router.all(
  "/graphql",
  koaMiddleware(server, {
    context: async ({ ctx }) => ({ token: ctx.headers.token }),
  })
);

app.use(router.routes()) ;
app.use(router.allowedMethods());
quirkybird commented 10 months ago

@matthew-gordon Thank you very much for your patience