menu

Apollo

A community of developers, designers and others who love Apollo and GraphQL. 🚀

Channels
Team

To update the schema on apollo-gateway without restarting the apollo-server?

January 28, 2020 at 1:02am

To update the schema on apollo-gateway without restarting the apollo-server?

January 28, 2020 at 1:02am
I have the GraphQL service started with schema & executor from ApolloGateway. When the schema is updated at the underlying service, I'd like to programmatically reload the federated schema without restarting the service (ideally to avoid to stop the .listen(4000), too).
const gateway = new ApolloGateway({
serviceList: [
{ name: "user", url: `http://localhost:4001/` },
{ name: "product", url: `http://localhost:4002/` },
],
const { schema, executor } = await gateway.load()
const server = new ApolloServer({
schema,
executor}).listen(4000, "0.0.0.0")
I found this thread talked about a few different approaches to hot reload: https://github.com/apollographql/apollo-server/issues/1275 But the thread has been closed without a solid answer. What is the recommended way to achieve dynamical update of schema?

February 2, 2020 at 1:58am
If I understand the question correctly, you can either: a) use managed federation by using graph manager to keep a centralized state of schemas and push updates to it when your services update; or b) you can set up polling by calling startPollingServices() on the gateway after the gateway is up and running.
The latter is not recommended for production.
Edited
  • reply
  • like

February 2, 2020 at 10:02pm
Hi, there is even an option for polling... You can initialize your gateway using const gateway = new ApolloGateway({ experimental_pollInterval: 10000... }) but as the name indeed says, it is not for production. I tried this and changed a lot at the downstream services. Worked pretty good though so it is sufficient for development at least....
  • reply
  • like

February 3, 2020 at 7:29pm
Thanks for the reply. In my case, I setup a REST call with apollo-server-express to let reloading be triggered by human / by deployment script, and the call invokes this procedure to reload the GraphQL schema with this snippet:
async function reloadSchema(apolloServer, apolloGateway) {
console.log("Start reloading GraphQL schema...");
const { schema, executor } = await apolloGateway.load();
const schemaDerivedData = await apolloServer.generateSchemaDerivedData(schema);
apolloServer.schema = schema;
apolloServer.schemaDerivedData = schemaDerivedData;
apolloServer.config.schema = schema;
apolloServer.config.executor = executor;
apolloServer.requestOptions.executor = executor;
console.log("Completed reloading GraphQL schema");
}
Briefly tested in playground, the snippet seemed to work, but feeling like a hack. Is there a method to reload schema provided by Apollo-Server?
Edited
  • reply
  • like

July 27, 2020 at 6:51am
Thanks for the reply. In my case, I setup a REST call with apollo-server-express to let reloading be triggered by human / by deployment script, and the call invokes this procedure to reload the GraphQL schema with this snippet:
async function reloadSchema(apolloServer, apolloGateway) {
console.log("Start reloading GraphQL schema...");
const { schema, executor } = await apolloGateway.load();
const schemaDerivedData = await apolloServer.generateSchemaDerivedData(schema);
apolloServer.schema = schema;
apolloServer.schemaDerivedData = schemaDerivedData;
apolloServer.config.schema = schema;
apolloServer.config.executor = executor;
apolloServer.requestOptions.executor = executor;
console.log("Completed reloading GraphQL schema");
}
Briefly tested in playground, the snippet seemed to work, but feeling like a hack. Is there a method to reload schema provided by Apollo-Server?
This is a solution worked for me. For ApollogGateway, instead of hardcoding the serviceList, abstract this out and maintain this list dynamically.
For the REST call, it accepts a request (new SDL for example), then concatenates this new SDL with the dynamic SDL list.
For the gateway, update it to have it read from the dynamic service list, using experimental_updateServiceDefinitions.
Lastly, add in the polling for the gateway, so it can get updated.
Edited
  • reply
  • like