如何在GraphQL Yoga服务器中添加并使用Scalar JSON类型?
嘿,我来帮你解决这个GraphQL Yoga里处理动态JSON结构的问题!你遇到的情况很典型——REST API返回的字段是动态的,没法提前在GraphQL schema里定义固定字段,这时候JSON标量就是最佳方案。下面一步步教你怎么配置:
方法一:使用现成的
graphql-scalars库(推荐) 这个库已经封装好了常用的标量类型(包括JSON),直接用就行,省得自己写复杂的解析逻辑:
- 先安装依赖:
npm install graphql-scalars # 或者用yarn yarn add graphql-scalars
- 在你的GraphQL Yoga配置里导入并配置JSON标量:
import { createYoga } from 'graphql-yoga'; import { JSONScalar } from 'graphql-scalars'; // 定义schema,先声明JSON标量 const typeDefs = ` scalar JSON type Task { orders: JSON } type Query { getTasks: Task } `; const resolvers = { // 把导入的JSON标量绑定到schema的JSON类型上 JSON: JSONScalar, Query: { getTasks: () => { // 模拟你的REST API返回数据 return { orders: { "PMY5XbR7FZo5qEkEb": 0 } }; } } }; // 创建Yoga服务器 const yoga = createYoga({ schema: { typeDefs, resolvers } }); // 启动服务器(根据你的环境配置端口等)
这样你就能在Task类型里用JSON标量来处理动态结构的orders对象了。
方法二:手动实现JSON标量类型
如果你不想额外加依赖,也可以自己实现JSON标量的解析和序列化逻辑:
import { createYoga, GraphQLScalarType, Kind } from 'graphql-yoga'; // 自定义JSON标量类型 const JSONScalar = new GraphQLScalarType({ name: 'JSON', description: '用于处理任意JSON结构的自定义标量', // 把JS对象序列化为JSON返回给客户端 serialize(value) { return value; }, // 解析客户端传入的变量值 parseValue(value) { return value; }, // 解析GraphQL查询里的字面量语法 parseLiteral(ast) { switch (ast.kind) { case Kind.STRING: try { return JSON.parse(ast.value); } catch (e) { throw new Error('JSON标量解析字符串失败,请传入合法JSON'); } case Kind.OBJECT: case Kind.ARRAY: case Kind.NULL: case Kind.BOOLEAN: case Kind.INT: case Kind.FLOAT: return ast.value; default: throw new Error(`无法解析类型为${ast.kind}的JSON标量`); } } }); const typeDefs = ` scalar JSON type Task { orders: JSON } type Query { getTasks: Task } `; const resolvers = { JSON: JSONScalar, Query: { getTasks: () => ({ orders: { "PMY5XbR7FZo5qEkEb": 0 } }) } }; const yoga = createYoga({ schema: { typeDefs, resolvers } });
为什么你之前的定义不生效?
你之前直接写type Task { orders: JSON }但没做两件关键的事:
- 没有在schema开头用
scalar JSON声明这个自定义标量类型,GraphQL根本不知道JSON是什么 - 没有在resolvers里提供
JSON类型的具体实现逻辑
只有同时完成这两步,Yoga才能正确识别并处理这个标量类型。
内容的提问来源于stack exchange,提问作者Josh Pittman
相关产品推荐
相关产品推荐

