如何更新Express GraphQL已挂载的GraphQL Schema使之在接口生效?
问题原因
你当前的写法会在服务启动挂载中间件时,直接将初始schema静态传入expressGraphQL实例,后续修改schema变量的引用不会被已经初始化完成的中间件实例读取,因此不会生效。
可用解决方案
方案1:使用函数式配置(最推荐)
express-graphql原生支持传入返回配置对象的函数作为参数,函数会在每次请求触发时执行,天然可以拿到最新的schema变量:
app.use("/graphql", expressGraphQL((req, res) => { return { schema: schema, // 直接引用你动态更新的schema变量即可 graphiql: true } }))
如果你的schema生成逻辑是异步的,也可以用async函数:
app.use("/graphql", expressGraphQL(async (req, res) => { const latestSchema = await getUpdatedSchema() // 你的异步schema生成逻辑 return { schema: latestSchema, graphiql: true } }))
方案2:中间件动态重载(适合低更新频率场景)
如果你的schema更新频率极低,不想每次请求都执行配置逻辑,可以封装一层中间件代理,更新schema时直接替换代理指向的中间件实例:
// 初始化中间件代理 let currentGraphqlMiddleware = expressGraphQL({ schema: schema, graphiql: true }) // 挂载代理层 app.use("/graphql", (req, res, next) => { currentGraphqlMiddleware(req, res, next) }) // schema更新时调用该方法即可 function updateGraphQLSchema(newSchema) { currentGraphqlMiddleware = expressGraphQL({ schema: newSchema, graphiql: true }) }
注意事项
- 方案1要求
express-graphql版本≥v0.10.0,低于该版本的话需要先升级依赖。 - 如果你的服务是多实例部署,需要自行保证所有实例的schema同步更新。
内容的提问来源于stack exchange,提问作者Will Lo
相关产品推荐
相关产品推荐

