graphql-mesh
graphql-mesh copied to clipboard
Service Polling / Live Schema Updates - Possible?
It is possible to have the mesh gateway poll running services for schema changes? Or trigger it to reload its sources somehow?
Current code snippet I am experimenting with:
const { ApolloServer } = require('apollo-server')
const { findAndParseConfig } = require('@graphql-mesh/config')
const { getMesh } = require('@graphql-mesh/runtime')
async function main() {
const meshConfig = await findAndParseConfig();
const { schema, contextBuilder } = await getMesh(meshConfig);
const context = await contextBuilder({
testProp: 'test'
})
const apolloServer = new ApolloServer({
schema,
context
});
const { url } = await apolloServer.listen(4000);
console.info(`π Server ready at ${url}`);
}
main().catch(err => console.error(err));
I need this too.
I need this too. Only way to do is to restart the mesh serve process and that will not be so nice once its deployed to production :/
Right now I'm using mesh in front of Hasura, I have them both running in local for development.
What I do is :
- Listen for changes on Hasura's metadata folder (it means Hasura's GraphQL API had potential changes). When there is a change, I have a command that forces a reboot of
mesh dev
(using nodemon and rebuilding a file does the job) - Once
mesh dev
is rebooted and healthy, I run agraphql-codegen
command to introspect the schema and generate myschema.graphql
- As my
schema.graphql
changed, all my codegen pipeline is triggered βοΈ
The scripts look like this :
"graphql-codegen:get-schema": "concurrently yarn:graphql-codegen:get-schema-*",
"graphql-codegen:on-hasura-change": "chokidar \"packages/server/hasura/**/*\" --command \"yarn workspace @clovis/server run proxy:reload && yarn graphql-codegen:get-schema\" --silent",
"proxy:dev": "nodemon --watch .meshrc.yml --watch src/app/proxy --exec yarn proxy:start",
"proxy:start": "wait-port http://localhost:8080/healthz && mesh dev --dir src/app/proxy --require dotenv/config",
"proxy:reload": "cat .meshrc.yml | tee .meshrc.yml > /dev/null",
To simplify everything it would be awesome if mesh dev
could poll for remote schema changes and automatically generate the schema.graphql
. π
I know this is not ideal, but here is another approach using Docker and Kubernetes. In my Dockerfile
, I wrote:
FROM node:16.13-alpine
# ...
RUN npm i -g pm2
# ...
ENTRYPOINT ["/bin/sh", "/app/update-schemas.sh"]
CMD pm2-runtime '/app/node_modules/.bin/mesh start' --no-autorestart --wait-ready --name mesh --listen-timeout 15000
Then in my update-schemas.sh
:
nohup sh -c "sleep 60 && yarn mesh build && pm2 reload all"
export $NEXT_RESTART_MINUTE=`date +"%M"`
echo "$NEXT_RESTART_MINUTE * * * * cd /app && yarn mesh build && pm2 reload all" >> /etc/crontab/root
crond -l 2 -f > /dev/stdout 2> /dev/stderr &
exec "$@"
What's happening here:
- After 1 minute, I run a new build of the unified schema. IF the build is successful, I trigger a reload of the server, otherwise I keep running my outdated schema
- Every hour I repeat the same (i.e., a build and reload if successful)
- Why
pm2
? Because if I kill the mesh process directly, my docker container dies - Why I did not use
yarn mesh start
in myCMD
line? Because otherwise pm2 wasn't able to kill the old mesh process.
A few gotchas:
- This is very hacky...
- It is not smart, it polls every hour a full reload, it does not detect each source individually
- If any plugged API breaks or is offline, it won't update anything at all