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

How to customize GraphQL query validation error message

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

错误:

{
"data": null,
"errors": [
    {
         value=StringValue{value='1235'}}]}}]}' is missing required fields '[book_type]' @ 'create_book'",
        "locations": [
            {
                "line": 3,
                "column": 23,
                "sourceName": null
            }
        ],
        "description": "argument 'insert' with value value=StringValue{value='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因为这是来自客户的错误请求

首先,您应该在 ExecutionResult 上调用 toSpecification() 以确保响应遵循 GraphQL Specification.

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

ExecutionResultImpl 内部包含 检测到的所有错误。它们都在 GraphQLError 的 subclass 中,这意味着您必须在自定义时将其转换为特定的 sub-class。

在你的情况下,subclass 是 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);
}