如何自定义 GraphQL 查询验证错误消息

Posted

技术标签:

【中文标题】如何自定义 GraphQL 查询验证错误消息【英文标题】:How to customize GraphQL query validation error message 【发布时间】:2020-05-28 15:49:10 【问题描述】:

我正在通过使用GraphQl 和spring boot 项目对sql 数据库执行CRUD 操作来实现数据库查询层。在 GraphQL 模式中,我提到了一些必须的字段,当查询中未提及这些字段时,它会以默认格式返回 ValidationError 错误消息,并带有 200 状态码。

错误:


"data": null,
"errors": [
    
         value=StringValuevalue='1235']]' is missing required fields '[book_type]' @ 'create_book'",
        "locations": [
            
                "line": 3,
                "column": 23,
                "sourceName": null
            
        ],
        "description": "argument 'insert' with value value=StringValuevalue='1235']]' is missing required fields '[book_type]'",
        "validationErrorType": "WrongType",
        "queryPath": [
            "create_book"
        ],
        "errorType": "ValidationError",
        "path": null,
        "extensions": null
    
],
"dataPresent": false,
"extensions": null

这是我的分层架构模式代码

控制器:

@Autowired
private GraphQLServer graphQlServer;

@PostMapping("test")
public ResponseEntity<Object> graphQl(@RequestBody String body)
    ExecutionResult response = graphQlServer.execute(body);

    return ResponseEntity.ok(response);

服务:

@Service
public class GraphQLServer 

@Autowired
private GraphQL graphQl;

public ExecutionResult execute(String query) 
    return graphQl.execute(query);
   


配置:

@Bean
public GraphQL loadSchema() throws IOException 

    File schemaFile = schemaResource.getFile();

    TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(schemaFile);
    RuntimeWiring wiring = buildRuntimeWiring();
    GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeRegistry, wiring);
    return GraphQL.newGraphQL(schema).build();


private RuntimeWiring buildRuntimeWiring() 

    return RuntimeWiring.newRuntimeWiring()
            .type("Mutation", mutationWiring -> mutationWiring.dataFetcher("create_book", bookDataFetcher))
            .build();


BookDataFetcher:

@Override
public Map<String, Object> get(DataFetchingEnvironment environment) 

    //return data from db by getting Map properties from environment


上述代码按预期工作,但我的问题是如何自定义错误消息?在错误消息中我想提及状态400,因为它是来自客户端的错误请求

【问题讨论】:

你知道哪个是具有dataerrorsdataPresentextensions等字段的JSON对象吗?如果你知道的话,我可以帮你@Deadpool 【参考方案1】:

首先,您应该在ExecutionResult 上调用toSpecification(),以确保响应符合GraphQL Specification。

默认情况下,graphql-java 只提供了一个ExecutionResult 的实现,即ExecutionResultImpl,因此您可以将ExecutionResult 转换为它,以便使用它的transform() 来更新其状态。

ExecutionResultImpl 内部包含graphql-java 检测到的所有错误。它们都在GraphQLError 的子类中,这意味着您必须在自定义期间将其转换为特定的子类。

在你的情况下,子类是ValidationError,代码看起来像:

@PostMapping("test")
public ResponseEntity<Object> graphQl(@RequestBody String body)

    ExecutionResult response = graphQlServer.execute(body);

    ExecutionResultImpl responseImpl = (ExecutionResultImpl) response;

    List<GraphQLError> customizedErrors = Lists.newArrayList();
    for (GraphQLError gqlError : responseImpl.getErrors()) 
            //Do your error custmosation here....
            GraphQLError customizedError = gqlError;
            if (gqlError instanceof ValidationError) 
                ValidationError error = (ValidationError) gqlError;
                customizedError = new ValidationError(error.getValidationErrorType(), error.getLocations(),
                        "Customizing some error message blablabla....");
            
            customizedErrors.add(customizedError);
    

    Map<String, Object> specResponse = responseImpl.transform(b->b.errors(customizedErrors)).toSpecification();

    return ResponseEntity.ok(specResponse);

【讨论】:

以上是关于如何自定义 GraphQL 查询验证错误消息的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL - 突变响应后的自定义错误消息

如何从控制器方法验证返回自定义错误消息

Django,自定义身份验证登录。身份验证失败时如何显示错误消息?

如何根据 Angular 2 中的自定义验证规则显示错误消息?

如何自定义 django jwt graphql 身份验证

如何自定义 laravel 数组验证错误键和消息