6

In Apollo Federation, I am facing this problem: The gateway needs to be restarted every time we make a change in the schema of any federated service in service list. I understand that every time a gateway starts and it collects all the schema and aggregates the data graph. But is there a way this can be handled automatically without restarting the Gateway as it will down all other unaffected GraphQL Federated services also

Apollo GraphQL , @apollo/gateway

A.K
  • 320
  • 5
  • 14

3 Answers3

2

There is an experimental poll interval you can use:

const gateway = new ApolloGateway({
  serviceList: [
    { name: "products", url: "http://localhost:4002" },
    { name: "inventory", url: "http://localhost:4001" },
    { name: "accounts", url: "http://localhost:4000" }
  ],
    debug: true,
    experimental_pollInterval:3000
})

the code above will pull every 3 seconds

Olivier Refalo
  • 50,287
  • 22
  • 91
  • 122
  • i tried this , but the problem is that this isnt advisable in production environment and even apollo says the same . :( – A.K Oct 31 '19 at 15:23
  • Note that you are adding requirements to your original question. There is no better OOB solution at this point. Sincerely – Olivier Refalo Nov 04 '19 at 06:27
2

I don't know other ways to automatically reload the gateway other than polling. I made a reusable docker image and i will keep updating it if new ways to reload the service emerge. For now you can use the POLL_INTERVAL env var to periodically check for changes. Here is an example using docker-compose:

version: '3'

services:
    a:
        build: ./a # one service implementing federation
    b:
        build: ./b
    gateway:
        image: xmorse/apollo-federation-gateway
        ports:
            - 8000:80
        environment: 
            CACHE_MAX_AGE: '5' # seconds
            POLL_INTERVAL: '30' # seconds
            URL_0: "http://a"
            URL_1: "http://b"
Morse
  • 61
  • 1
  • 2
2

You can use express to refresh your gateway's schema. ApolloGateway has a load() function that go out to fetch the schemas from implementing services. This HTTP call could potentially be part of a deployment process if something automatic is needed. I wouldn't go with polling or something too automatic. Once the implementing services are deployed, the schema is not going to change until it's updated and deployed again.

import { ApolloGateway } from '@apollo/gateway';
import { ApolloServer } from 'apollo-server-express';
import express from 'express';

const gateway = new ApolloGateway({ ...config });
const server = new ApolloServer({ gateway, subscriptions: false });
const app = express();

app.post('/refreshGateway', (request, response) => {
  gateway.load();
  response.sendStatus(200);
});

server.applyMiddleware({ app, path: '/' });

app.listen();

Update: The load() function now checks for the phase === 'initialized' before reloading the schema. A work around might be to use gateway.loadDynamic(false) or possibly change gateway.state.phase = 'initialized';. I'd recommend loadDyamic() because change state might cause issues down the road. I have not tested either of those solutions since I'm not working with Apollo Federation at the time of this update.

  • This is a great solution, but is it documented anywhere? The Gateway docs at https://www.apollographql.com/docs/federation/api/apollo-gateway/ don't mention `load`. – Nate Sep 30 '21 at 18:55
  • 1
    @Nate They have removed the documentation around `load` if it ever existed. I saw this in some apollo-gateway code and thought it was appropriate for this use case. – Andrew Giangrant Oct 05 '21 at 22:39
  • And… it no longer works. This was a great solution but in recent versions it reports "Error: ApolloGateway.load called in surprising state loaded". It seems they want to push you to use their Managed Federation service. – Nate Oct 21 '21 at 13:15
  • 1
    That's a bummer. I suppose, the original solution should be taken with a grain of salt as it was undocumented (probably for that reason). You can give `gateway.loadDynamic(false)` a try. You might be able to hack the Apollo phase state to be 'initialized' too. The only other solution that comes to mind is using another schema system, which seems overly complicated to get working with Apollo Gateway. – Andrew Giangrant Nov 05 '21 at 13:16