You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用express-graphql时GraphQL Mutation无法正常工作求助

排查express-graphql + swagger-to-graphql Mutation POST请求报错问题

我来帮你分析下这个问题,你遇到的uncaughtException: First argument must be a string or Buffer错误,大概率是POST请求的请求体没有被正确序列化为JSON字符串导致的,结合你的场景,咱们从这几个方向排查:

1. 先检查Swagger Schema的请求体定义是否正确

swagger-to-graphql完全依赖Swagger Schema生成GraphQL操作,首先要确认你的schema.json里addPet接口的请求体配置没问题:

  • 找到paths下/pet的post方法,确认requestBody(Swagger 3.0)或parameters(Swagger 2.0)是否正确标记了application/json类型,并且字段定义和你传入的Mutation参数匹配。
  • 比如Swagger 3.0的正确配置应该类似这样:
    "/pet": {
      "post": {
        "summary": "Add a new pet to the store",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Pet"
              }
            }
          }
        }
      }
    }
    
  • 再检查components/schemas/Pet的定义,确保id的类型是string(你传的是"111"字符串),name是必填字符串,photoUrls是字符串数组——如果类型不匹配,swagger-to-graphql可能无法正确转换请求体。

2. 升级依赖并调整代理地址配置

旧版本的swagger-to-graphql存在请求体序列化的bug,先升级依赖试试:

npm update swagger-to-graphql express-graphql

另外,你的GQLProxyBaseUrl末尾带了斜杠,可能导致接口地址拼接错误(比如变成http://localhost:3000/api/v2//pet),改成不带末尾斜杠的版本:

context: {
  GQLProxyBaseUrl: 'http://localhost:3000/api/v2',
},

3. 自定义Fetch逻辑强制序列化请求体

如果升级后还是报错,那可以手动干预swagger-to-graphql的请求发送逻辑,强制把请求体序列化为JSON字符串。修改你的代码如下:

'use strict';
var graphqlHTTP = require('express-graphql');
var graphQLSchema = require('swagger-to-graphql');
var pathToSwaggerSchema = require('./schema.json');
const fetch = require('node-fetch'); // 需要先安装node-fetch:npm install node-fetch

module.exports = function(server) {
 var router = server.loopback.Router();
 router.get('/', server.loopback.status());

 graphQLSchema(pathToSwaggerSchema, {
  // 自定义fetch逻辑,处理POST/PUT请求体
  customFetch: async (url, options) => {
    if (['POST', 'PUT'].includes(options.method)) {
      // 把对象类型的body序列化为JSON字符串
      options.body = JSON.stringify(options.body);
      // 确保Content-Type是application/json
      options.headers = {
        ...options.headers,
        'Content-Type': 'application/json',
      };
    }
    return fetch(url, options);
  }
 }).then(schema => {
 server.use('/graphql', graphqlHTTP((req) => {
 return {
 schema: schema,
 context: {
 GQLProxyBaseUrl: 'http://localhost:3000/api/v2',
 },
 graphiql: true,
 };
 }));
 }).catch(e => {
 throw e;
 });

 server.use(router);
};

这个方法强制将请求体转换成JSON字符串,解决了"First argument must be a string or Buffer"的核心问题。

4. 调试验证请求内容

如果还是有问题,可以在customFetch里加日志,打印实际发送的url和options,确认请求体的内容和类型:

customFetch: async (url, options) => {
  console.log('请求地址:', url);
  console.log('请求方法:', options.method);
  console.log('请求体类型:', typeof options.body);
  console.log('请求体内容:', options.body);
  // ...后续处理逻辑
}

通过日志可以直观看到请求体是否是字符串类型,以及内容是否符合后端接口的要求。


内容的提问来源于stack exchange,提问作者zulekha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:40:10