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

如何在GraphQL Pothos中创建自定义JSONObject标量类型?

问题描述

尝试创建自定义标量JSONObject用于接收JSON格式的文档数组作为mutation的输入参数,但无法正常工作。该标量已显示在GraphiQL界面中,但系统始终提示字段需为定义的JSONObject类型。尝试过使用预定义的JSONResolver以及两种自定义标量实现,问题依旧。需要接收的输入格式为:

[{ 
"weight": 0, 
"spotsAvailable": [{ "userId": "empty", "name": "empty" }, { "userId": "67fd6sdhfds7yf87", "name": "John" }]
 }, { 
"weight": 0, 
"spotsAvailable": [{ "userId": "empty", "name": "empty" }, { "userId": "67fd6sdhfds7yf87", "name": "John" }] }]
解决方案

1. 修正自定义标量的解析逻辑

现有自定义标量存在两处关键问题:

  • 首个实现强制要求输入包含_id字段,与需求的数组格式冲突
  • 两个实现均缺失parseLiteral方法,GraphQL处理查询字面量时会因此解析失败

修改后的自定义标量实现:

builder.scalarType('JSONObject', {
  serialize: (value) => {
    // 序列化时直接返回值,确保输出符合JSON格式
    return value;
  },
  parseValue: (value: any) => {
    // 允许对象或数组,且非空非undefined
    if ((typeof value === 'object' && value !== null) || Array.isArray(value)) {
      return value;
    }
    throw new Error('JSONObject必须是对象或数组类型');
  },
  // 处理GraphQL AST节点解析,必须实现
  parseLiteral: (ast) => {
    switch (ast.kind) {
      case Kind.OBJECT:
      case Kind.LIST:
        return ast.value;
      default:
        throw new Error('JSONObject只能解析对象或数组类型的字面量');
    }
  }
});

2. 修复Mutation中的参数获取错误

createEvent的resolve函数中错误使用argWeights变量,实际输入参数为weights,导致值无法正确传递。修正后的代码:

resolve: (_, { input: { longitude, latitude, name, date, description, cost, link, weights } }, context) => {
  const location: Location = {
    type: 'Point',
    coordinates: [longitude, latitude]
  };

  let anObject = {
    createdBy: context.currentUser._id as ObjectId,
    location,
    name,
    date,
    description,
    cost: cost ?? undefined,
    link: link ?? undefined,
    weights: weights ?? undefined
  };

  return dbMutations.createEvent(anObject);
}

3. 确认标量注册与类型定义匹配

若使用自定义标量,需移除builder.addScalarType('JSONObject', JSONResolver, {})避免冲突,保留如下类型定义即可:

Scalars: {
  Date: {
    Input: Date;
    Output: Date;
  };
  mongoId: {
    Input: ObjectId;
    Output: ObjectId;
  };
  JSONObject: {
    Input: any;
    Output: any;
  };
  objectIdOrEmpty: {
    Input: ObjectId | Empty;
    Output: ObjectId | Empty;
  };
};

4. GraphiQL输入验证

测试mutation时确保weights字段为合法JSON数组,示例查询:

mutation CreateEvent($input: CreateEventInput!) {
  createEvent(input: $input) {
    _id
    name
    weights
  }
}

变量:

{
  "input": {
    "longitude": 120.123,
    "latitude": 30.456,
    "name": "Test Event",
    "date": "2024-12-31T12:00:00Z",
    "description": "Test Description",
    "weights": [
      { 
        "weight": 0, 
        "spotsAvailable": [{ "userId": "empty", "name": "empty" }, { "userId": "67fd6sdhfds7yf87", "name": "John" }]
      },
      { 
        "weight": 0, 
        "spotsAvailable": [{ "userId": "empty", "name": "empty" }, { "userId": "67fd6sdhfds7yf87", "name": "John" }]
      }
    ]
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:31:01