From a6b2cd4ef572be8bf8c62fe8d613f29aa2dbbe42 Mon Sep 17 00:00:00 2001 From: Fredrik Fornwall Date: Fri, 8 May 2020 10:05:23 +0200 Subject: [PATCH] Fix internal server by tightening API spec By specifying more constraints in the openapi.yaml file we can avoid possible exceptions and internal server errors and instead get descriptive validation messages on bad input. The curl -D- -X POST -H "Content-Type: application/json" --data "{}" http://localhost:8080/v3/store/order request previously returned: HTTP/1.1 500 2020-05-08T08:00:36.259Z500Internal Server Errorentity ID cannot be null/v3/store/order After this change it returns: HTTP/1.1 400 2020-05-08T08:03:46.408Z400Bad RequestNotNull.order.idNotNull.idNotNull.java.lang.LongNotNullorder.ididididmust not be nullorderidfalseNotNullValidation failed for object='order'. Error count: 1/v3/store/order The curl -D- -X DELETE http://localhost:8080/v3/store/order/- request previously returned: HTTP/1.1 500 {"timestamp":"2020-05-08T08:01:49.014Z","status":500,"error":"Internal Server Error","message":"For input string: \"-\"","path":"/v3/store/order/-"} After this change it returns: HTTP/1.1 400 {"timestamp":"2020-05-08T08:04:16.419Z","status":400,"error":"Bad Request","message":"Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: \"-\"","path":"/v3/store/order/-"} The curl -D- -X POST -H "Content-Type: application/json" --data "{}" http://localhost:8080/v3/user request previously returned: HTTP/1.1 500 {"timestamp":"2020-05-08T08:02:27.174Z","status":500,"error":"Internal Server Error","message":"entity ID cannot be null","path":"/v3/user"} After this change it returns: HTTP/1.1 400 {"timestamp":"2020-05-08T08:04:38.026Z","status":400,"error":"Bad Request","errors":[{"codes":["NotNull.user.id","NotNull.id","NotNull.java.lang.Long","NotNull"],"arguments":[{"codes":["user.id","id"],"arguments":null,"defaultMessage":"id","code":"id"}],"defaultMessage":"must not be null","objectName":"user","field":"id","rejectedValue":null,"bindingFailure":false,"code":"NotNull"},{"codes":["NotNull.user.username","NotNull.username","NotNull.java.lang.String","NotNull"],"arguments":[{"codes":["user.username","username"],"arguments":null,"defaultMessage":"username","code":"username"}],"defaultMessage":"must not be null","objectName":"user","field":"username","rejectedValue":null,"bindingFailure":false,"code":"NotNull"}],"message":"Validation failed for object='user'. Error count: 2","path":"/v3/user"} --- .../java/org/openapitools/api/StoreApiDelegateImpl.java | 4 ++-- src/main/resources/openapi.yaml | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/openapitools/api/StoreApiDelegateImpl.java b/src/main/java/org/openapitools/api/StoreApiDelegateImpl.java index 029a16c..6117ca1 100644 --- a/src/main/java/org/openapitools/api/StoreApiDelegateImpl.java +++ b/src/main/java/org/openapitools/api/StoreApiDelegateImpl.java @@ -46,8 +46,8 @@ void initOrders() { @Override - public ResponseEntity deleteOrder(String orderId) { - Order order = orderRepository.findById(Long.valueOf(orderId)) + public ResponseEntity deleteOrder(Long orderId) { + Order order = orderRepository.findById(orderId) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); orderRepository.delete(order); return ResponseEntity.ok().build(); diff --git a/src/main/resources/openapi.yaml b/src/main/resources/openapi.yaml index f9d7b26..6ca5897 100644 --- a/src/main/resources/openapi.yaml +++ b/src/main/resources/openapi.yaml @@ -382,7 +382,8 @@ paths: style: simple explode: false schema: - type: string + type: integer + format: int64 responses: 400: description: Invalid ID supplied @@ -598,6 +599,8 @@ components: Order: title: Pet Order type: object + required: + - id properties: id: type: integer @@ -649,6 +652,9 @@ components: User: title: a User type: object + required: + - id + - username properties: id: type: integer