如何自定义 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
,因为它是来自客户端的错误请求
【问题讨论】:
你知道哪个是具有data
、errors
、dataPresent
和extensions
等字段的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 查询验证错误消息的主要内容,如果未能解决你的问题,请参考以下文章
Django,自定义身份验证登录。身份验证失败时如何显示错误消息?