Apollo-server: Unable to change graphqlPath

Created on 5 Sep 2018  路  4Comments  路  Source: apollographql/apollo-server

Using the [email protected], I can change the port but I'm having trouble changing the graphql path. I tried the following to no avail.

const server = new ApolloServer({...});
server.setGraphQLPath('/graphql');
server.graphqlPath = '/graphql';
server.listen({port: 3000, path: '/graphql'}).then(({ url }) => {
   console.log(`馃殌 Server ready at ${url}`);
});

logs: 馃殌 Server ready at http://localhost:3000

Most helpful comment

I'm assuming you are using the basic example with the apollo-server package?

tl;dr:

To set a custom path, you would need to use a middleware option such as apollo-server-express

Long Explanation:

The basic example from the docs creates a server that listens for requests on all paths, on either the default port 4000, or a port you define in the listen step: server.listen({ port: 3000 })...

Note: If using the basic ApolloServer example with server.listen(), Apollo is creating an internal httpServer with express for you. To access and customize this express server, use the apollo-server-express package directly.

The ApolloServer instance sets it's graphqlPath internally to /graphql and may use that for subscriptions etc. But internally, it's using an instance of express, where it listens on / (all paths). You can confirm this a few ways:

With a default config, you can startup the server and use a browser to visit http://localhost:4000/any/random/path. You should get the Playground UI.

Or send a valid GraphQL request to http://localhost:3000/any/random/path and it should still work.

Apollo Server Source Snippet

You can see the path is /. Express route matching logic would match any request starting with /. Source

// This class is the easy mode for people who don't create their own express
// object, so we have to create it.
const app = express();

// provide generous values for the getting started experience
super.applyMiddleware({
      app,
      path: '/',
      bodyParserConfig: { limit: '50mb' },`

Hopefully that helps? This question has come up a few times, so I wanted to try to provide a (hopefully correct) explanation.

All 4 comments

I'm assuming you are using the basic example with the apollo-server package?

tl;dr:

To set a custom path, you would need to use a middleware option such as apollo-server-express

Long Explanation:

The basic example from the docs creates a server that listens for requests on all paths, on either the default port 4000, or a port you define in the listen step: server.listen({ port: 3000 })...

Note: If using the basic ApolloServer example with server.listen(), Apollo is creating an internal httpServer with express for you. To access and customize this express server, use the apollo-server-express package directly.

The ApolloServer instance sets it's graphqlPath internally to /graphql and may use that for subscriptions etc. But internally, it's using an instance of express, where it listens on / (all paths). You can confirm this a few ways:

With a default config, you can startup the server and use a browser to visit http://localhost:4000/any/random/path. You should get the Playground UI.

Or send a valid GraphQL request to http://localhost:3000/any/random/path and it should still work.

Apollo Server Source Snippet

You can see the path is /. Express route matching logic would match any request starting with /. Source

// This class is the easy mode for people who don't create their own express
// object, so we have to create it.
const app = express();

// provide generous values for the getting started experience
super.applyMiddleware({
      app,
      path: '/',
      bodyParserConfig: { limit: '50mb' },`

Hopefully that helps? This question has come up a few times, so I wanted to try to provide a (hopefully correct) explanation.

@sbrichardson thanks for the clarification. Does it mean that the apollo-server was not meant to use for use cases where you need to change the path? What is the advantage of apollo-server over apollo-server-express? Is apollo-server for example purposes only and we should opt to use the middleware (apollo-server-express)? Sorry, it's quite confusing for newcomers like me.

using apollo-server-express is technically the same thing as using the vanilla apollo-server, you just gain the ability to add middleware and other features.

When you use the vanilla/basic apollo-graphql, it's actually using express in the backend. I'm not an Apollo employee so can't comment on it directly, just wanted to clarify!

I wouldn't say it's for example purposes only. It depends on your use case and environment. It just has a minimal config to get you up and running quickly. Using the express version isn't much different, it's your choice.

You would use the express version specifically if you wanted to use the graphql server to server other requests on different paths, or add middleware before/after requests to do things outside the scope of apollo. Some use cases call for a more microservice approach, where some are monolithic in design. Using a microservice approach in kubernetes for example, the path wouldn't be an issue. You would have a gateway service such as Ambassador route requests to an auth service, then send them to a graphql service/pod. The server wouldn't be aware of the path etc, it would just handle the request.

Usually in production you would use a gateway/proxy service to handle requests anyways. They use path matching just like express to know which service to send a request. So if you want https://yourapp.com/api/v1 to go to your graphql server, you would just tell nginx/envoy/ambassador etc to send /api/v1 > /graphql on the backend.

Hopefully that clarifies a bit?

thanks @sbrichardson! Thanks for all the information, that clears it up for me.

Was this page helpful?
0 / 5 - 0 ratings