Как настроить сообщение об ошибке проверки запроса GraphQL - PullRequest
1 голос
/ 13 февраля 2020

Я реализую слой запросов в базе данных, используя GraphQl и проект весенней загрузки для выполнения операции CRUD для базы данных sql. В схеме 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, так как это плохой запрос от клиента

1 Ответ

1 голос
/ 13 февраля 2020

Прежде всего, вы должны позвонить toSpecification() на ExecutionResult, чтобы убедиться, что ответ соответствует спецификации GraphQL .

По умолчанию существует только один ExecutionResult ' s реализация обеспечивается , что составляет ExecutionResultImpl, поэтому вы можете привести к нему ExecutionResult, чтобы использовать transform() для обновления его состояния.

ExecutionResultImpl содержит все ошибки, обнаруженные . Все они находятся в подклассе GraphQLError, что означает, что вы должны привести его к указанному подклассу c во время настройки.

В вашем случае подкласс 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...