Express GraphQL集成sofa-api遇问题:接口返回异常+Swagger无法加载
问题解决:Express GraphQL + Sofa-API 接口返回Null与Swagger界面加载失败问题
问题分析
你搭建的Express GraphQL服务中,/graphql路由正常但Sofa-API生成的/api/hello返回null,且Swagger界面无法加载,核心原因有两个:
- Sofa-API缺少查询执行器,无法调用GraphQL resolver
- 未配置Swagger UI路由来渲染生成的swagger.json
问题1:/api/hello返回null的解决方法
Sofa-API仅传入schema不足以执行查询,必须提供executor来处理GraphQL解析逻辑。修改useSofa配置,添加基于你的rootValue的执行器:
// 引入graphql核心模块 const { execute } = require('graphql'); // 修改useSofa配置 app.use( '/api', useSofa({ schema, basePath: '/api', // 添加executor,绑定rootValue executor: ({ document, variables }) => execute({ schema, document, rootValue: root, variables, }), onRoute(info) { openApi.addRoute(info, { basePath: '/api', }); }, }) );
添加executor后,Sofa-API就能正确调用你的hello resolver,返回"Hello World!"。
问题2:Swagger界面无法加载的解决方法
当前代码仅生成了swagger.json,但没有挂载Swagger UI的访问路由。需要安装并引入swagger-ui-express来托管这个文件:
步骤1:安装依赖
npm install swagger-ui-express
步骤2:添加Swagger UI路由
const swaggerUi = require('swagger-ui-express'); const swaggerDocument = require('./swagger.json'); // 在app.listen前添加 app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
现在访问/api/docs就能看到Swagger界面,而不是直接访问/api(/api是Sofa的REST接口前缀)。
修改后的完整代码
const express = require('express'); const { buildSchema, execute } = require('graphql'); const graphqlHTTP = require('express-graphql'); const { useSofa } = require('sofa-api'); const { OpenAPI } = require('sofa-api'); const { writeFileSync } = require('fs'); const swaggerUi = require('swagger-ui-express'); var schema = buildSchema(` type Query{ hello:String }`); const openApi = OpenAPI({ schema, info: { title: 'Example API', version: '3.0.0', }, }); var root = { hello: () => { return 'Hello World!'; }, }; var app = express(); app.use( '/graphql', graphqlHTTP({ schema: schema, rootValue: root, graphiql: true, }) ); app.use( '/api', useSofa({ schema, basePath: '/api', executor: ({ document, variables }) => execute({ schema, document, rootValue: root, variables, }), onRoute(info) { openApi.addRoute(info, { basePath: '/api', }); }, }) ); writeFileSync('./swagger.json', JSON.stringify(openApi.get(), null, 2)); // 新增Swagger UI路由 const swaggerDocument = require('./swagger.json'); app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); app.listen(4400);
内容的提问来源于stack exchange,提问作者SexyMF
相关产品推荐
相关产品推荐

