graphql-services / graphql-gateway

Apollo federation gateway wrapped in Docker image or AWS Lambda package.
MIT License
31 stars 8 forks source link

Implemented graphql gateway update interval #17

Closed hansehe closed 4 years ago

hansehe commented 4 years ago

The service works well, but I have a problem when backend services are updated and the graphql gateway doesn't fetch the new changes. This solution should simply solve the problem.

jakubknejzlik commented 4 years ago

Hello @hansehe, thanks for Your contribution. We are deploying this gateway usually in k8s or lambda and using following approach:

...so this approach is really welcome. Also there's a plan to create schema repository where You can push the schema from each service. Right now if one of the service is down during the initialization, it is basically removed from schema.

jakubknejzlik commented 4 years ago

Jobs for deployment has been restricted to tag/master only so the checks should not fail.

jakubknejzlik commented 4 years ago

@hansehe I'm checking the latest commit, but we probably not understood each other :)

What I meant by updating the middleware instance is:

const { getENV } = require("./env");
const express = require("express");
const { getApolloServer } = require("./apollo");

(async () => {
  const app = express();
  const jsonBodyLimit = getENV("GRAPHQL_JSON_BODY_LIMIT", "2mb");
  app.use(express.json({ limit: jsonBodyLimit }));

  const server = await getApolloServer();
  let middleware = server.getMiddleware({});
  app.use((req, res, next) => {
    middleware(req, res, next);
  });

  const activateUpdateGatewayInterval = getENV("GRAPHQL_UPDATE_GATEWAY", "false") === "true";
  const updateGatewayInterval = getENV("GRAPHQL_UPDATE_GATEWAY_INTERVAL_MS", "60000");
  if (activateUpdateGatewayInterval === true)
  {
    setInterval(async () => {
      try {
        const server = await getApolloServer();
        middleware = server.getMiddleware({}); // just update the already existing instance
      } catch (error) {
        console.error(error);
      }
    }, updateGatewayInterval);
  }

  const HOST = getENV("HOST", "http://localhost");
  const PORT = getENV("PORT", "80");

  app.listen({ port: PORT }, () => {
    console.log(`🚀 Server ready at ${HOST}:${PORT}/graphql`);
  });
})();

module.exports.getServer = getApolloServer;
hansehe commented 4 years ago

Ok, thanks again! I updated the code with your reviews and it works with my local testing.

jakubknejzlik commented 4 years ago

Perfect, lookgs ok! Thanks for Your patience :)

jakubknejzlik commented 4 years ago

Hello @hansehe again, sorry for bringing this up, but I just noticed that there's experimental_pollInterval. Although there's this thread: https://github.com/apollographql/apollo-server/discussions/4280 I believe switching to it could be easier. What do You think?