Validation GraphQL和表单验证错误
假设您有一个表单将数据发布到API服务器。API服务器验证输入并返回JSON对象。如果输入无效,则返回错误对象,如下面的对象Validation GraphQL和表单验证错误,validation,error-handling,graphql,Validation,Error Handling,Graphql,假设您有一个表单将数据发布到API服务器。API服务器验证输入并返回JSON对象。如果输入无效,则返回错误对象,如下面的对象 {errors: {field1: "is required"}} 在使用GraphQL时,我们如何处理和服务此类错误?应如何以及在何处实施数据验证(该验证是GraphQL的一部分还是应在每个解析函数中)?通过解析方法中的验证逻辑,您可以完全控制生成的用户错误。以下是一个例子: //data/mutations/createUser.js 进口{ GraphQLObje
{errors: {field1: "is required"}}
在使用GraphQL时,我们如何处理和服务此类错误?应如何以及在何处实施数据验证(该验证是GraphQL的一部分还是应在每个解析函数中)?通过
解析方法中的验证逻辑,您可以完全控制生成的用户错误。以下是一个例子:
//data/mutations/createUser.js
进口{
GraphQLObjectType作为ObjectType,
GraphQLNonNull作为非Null,
GraphQList作为列表,
GraphQLString作为StringType
}来自“graphql”;
从“验证器”导入验证器;
从“../types/UserType”导入UserType;
导出默认值{
类型:新对象类型({
名称:“CreateUserResult”,
字段:{
用户:{type:UserType},
错误:{type:new非空(new List(StringType))}
}
}),
args:{
电子邮件:{type:new NonNull(StringType)},
密码:{type:new非空(StringType)}
},
解析({email,password}){
让user=null;
让错误=[];
if(validator.isNull(电子邮件)){
错误。推送(…[“电子邮件”,“电子邮件字段不能为空”。]);
}else如果(!validator.isLength(电子邮件,{max:100})){
错误。推送(…[“电子邮件”,“电子邮件长度不得超过100个字符]);
}
//等等。
返回{user,errors};
}
};
请参阅我关于此主题的博客帖子-
或者,创建type usererrotype{key:String!,message:String!}
,当您编译要返回给调用方的用户错误列表时,可以使用它代替普通字符串
GraphQL查询
查询响应
看看这个包裹。它使得通过graphql响应上的errors数组发送机器可读的错误变得容易。然后,您可以将错误反馈到前端,并采取措施和/或向用户发出警告,告知发生了什么:
我使用一个小软件包来验证项目中的表单。这是我的。很容易使用
例如:
const { validator, validate } = require('graphql-validation'); // Import module
const resolver = {
Mutation: {
createPost: validator([ // <-- Validate here
validate('title').not().isEmpty({ msg: 'Title is required' }),
validate('content').isLength({ min: 10, max: 20 }),
], (parent, args, context, info) => {
if (context.validateErrors.length > 0) {
// Validate failed
console.log(context.validateErrors); // Do anything with this errors
return;
}
// Validate successfully, time to create new post
}),
},
};
希望它有用。我创建了一个用于以更好的方式处理GraphQL中的验证的工具。请检查npm包。最好将验证/能力检查放入服务层
GraphQL只是应用程序的一个入口点。因此,它不应该进行验证和能力检查
如果您想到一个具有多个访问层(REST和GraphQL)的应用程序。您将通过在GraphQL层中添加验证检查来复制代码
最好的方法是有一个代码层来处理这个问题,例如UserService。这将保留验证和功能检查的逻辑
GraphQL和RESTAPI只是将响应转换为相应响应类型的可接受格式的格式化程序。以下示例用于说明:
class UserService {
public function updateName(string $name) {
// validation/capability check code here.
// if validation fails, throw a user input exception or appropriate exception
//return value.
}
}
通过以这种方式在服务类中使用异常,您还可以选择希望在响应中返回的异常(可以是GraphQL或REST响应)
我们应该只将GraphQL视为一个访问层。解析程序函数应尽可能简单,不包含业务逻辑、验证和功能检查。这可能是我们将获得的最佳临时解决方案,除非GraphQL选择单独的错误对象来区分系统错误和用户字段/消息验证。我所做的唯一细微的更改是创建一个专用的ErrorType
,它具有字段
和msg
键,因此使用它比关心数组插入顺序稍微容易一些。。。但最终还是一样的,您还可以将验证端点引入GraphQL模式本身,或者在结果集中返回验证节点。
const { validator, validate } = require('graphql-validation'); // Import module
const resolver = {
Mutation: {
createPost: validator([ // <-- Validate here
validate('title').not().isEmpty({ msg: 'Title is required' }),
validate('content').isLength({ min: 10, max: 20 }),
], (parent, args, context, info) => {
if (context.validateErrors.length > 0) {
// Validate failed
console.log(context.validateErrors); // Do anything with this errors
return;
}
// Validate successfully, time to create new post
}),
},
};
Input: { title: '', content: 'Hi!' }
// console.log(context.validateErrors);
Output: [
{ param: 'title', msg: 'Title is required' },
{ param: 'content', msg: 'Invalid value' },
]
class UserService {
public function updateName(string $name) {
// validation/capability check code here.
// if validation fails, throw a user input exception or appropriate exception
//return value.
}
}
GraphQl Mutation
class UserResolver {
public function updateUserName(array $args, context $context) {
try {
$user = (new UserService() )->updateName(args['name']);
return [
'user' => $user
];
} catch (UserInputException $exception) {
return [
'error' => $exception,
'user' => null
];
}
}
}
REST API Controller
class UserController {
public function updateUserName(string $name) {
try {
$user = (new UserService() )->updateName($name);
return [
'user' => $user
];
} catch (UserInputException $exception) {
return [
'error' => $exception->message,
];
}
}
}