【问题标题】:Ensure GraphQL ID is a Mongo ObjectId确保 GraphQL ID 是 Mongo ObjectId
【发布时间】:2020-10-16 13:31:34
【问题描述】:
我正在使用 Apollo Server 构建一个基于 graphql 的服务器,该服务器与 MongoDB 实例交互。我想这样做,如果客户端传递一个具有 graphql 类型 ID 的字段的值,该值必须是有效的 mongo ObjectId(我认为 mongoose 有一个工具来检查这个 - 这不是问题)。也就是说,如果该值不是有效的 ObjectId,我希望在 graphql 级别得到验证错误(即 400)。当我尝试将该值用作 ObjectId 时,我不想稍后在我的服务器中获得 500,并且我不想在服务器内的多个位置检查该值是否是有效的 ObjectId。
如果有意义的话,基本上我想在 graphql 级别为 ID 标量类型实现验证逻辑。
【问题讨论】:
标签:
javascript
mongodb
validation
graphql
apollo
【解决方案1】:
您需要使用custom scalar 而不是ID 来获得您正在寻找的那种行为。您可以自己编写或使用existing one。
import { Kind, GraphQLError, GraphQLScalarType, ValueNode } from 'graphql';
const MONGODB_OBJECTID_REGEX = /*#__PURE__*/ new RegExp(/^[A-Fa-f0-9]{24}$/);
export const GraphQLObjectID = /*#__PURE__*/ new GraphQLScalarType({
name: 'ObjectID',
description:
'A field whose value conforms with the standard mongodb object ID as described here: https://docs.mongodb.com/manual/reference/method/ObjectId/#ObjectId. Example: 5e5677d71bdc2ae76344968c',
serialize(value: string) {
if (!MONGODB_OBJECTID_REGEX.test(value)) {
throw new TypeError(
`Value is not a valid mongodb object id of form: ${value}`,
);
}
return value;
},
parseValue(value: string) {
if (!MONGODB_OBJECTID_REGEX.test(value)) {
throw new TypeError(
`Value is not a valid mongodb object id of form: ${value}`,
);
}
return value;
},
parseLiteral(ast: ValueNode) {
if (ast.kind !== Kind.STRING) {
throw new GraphQLError(
`Can only validate strings as mongodb object id but got a: ${ast.kind}`,
);
}
if (!MONGODB_OBJECTID_REGEX.test(ast.value)) {
throw new TypeError(
`Value is not a valid mongodb object id of form: ${ast.value}`,
);
}
return ast.value;
},
});