400 Bad Request in Spring Boot Swagger UI for POST - spring-boot

I've created a Spring Boot application with RestController. I enabled Swagger UI and it works fine as I can login to the UI and execute any GET methods. But for POST methods accepting objects in the body, when I fire off the request using Swagger UI, it always returns 400 status code. I can see the request never reached the particular POST method. May I know if any special config I need for Swagger UI?
The particular method in my Spring Boot RestController
#ApiOperation(value = "Query requests by search criteria")
#RequestMapping(value = "/api/query", method = POST)
public PageResult<MyPOJO> find(#RequestBody SearchRequest request) {
//implementation omitted.
}
and I'm using
"io.springfox:springfox-swagger2:2.1.2",
"io.springfox:springfox-swagger-ui:2.1.2"
This one (generated by Swagger UI) for the corresponding api gives me 400 bad request:
{
"listEntrySearchCriteria": {
"summary": {
"createdBy": "string",
"createdOn": "2016-03-21T10:33:05.048Z",
"effectiveEnd": "2016-03-21T10:33:05.048Z",
"effectiveStart": "2016-03-21T10:33:05.048Z",
"id": 0,
"region": "string",
"type": "ETB",
"updatedBy": "string",
"updatedOn": "2016-03-21T10:33:05.048Z",
"version": 0
}
},
"listSummarySearchCriteria": {
"effectiveEnd": "2016-03-21T10:33:05.048Z",
"effectiveStart": "2016-03-21T10:33:05.048Z",
"statuses": [
"string"
],
"types": [
"string"
]
},
"pageRequest": {
"orders": [
{
"direction": "ASC",
"ignoreCase": true,
"nullHandling": "NATIVE",
"property": "string"
}
],
"page": 0,
"size": 0
}
}
But if I supply a random request for the same method, it at least reaches my method:
{
"orders": [
{
"direction": "ASC",
"ignoreCase": true,
"nullHandling": "NATIVE",
"property": "id"
}
],
"page": 0,
"size": 0
}

Related

HTTP metrics per endpoint uri in spring boot app

I have enabled actuator for my project. I am interested in metrics per endpoint uri in my application.
I have two endpoints / and /hello. When I visit /actuator/metrics/http.server.requests I get the following result:
{
"name": "http.server.requests",
"description": null,
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 11
},
{
"statistic": "TOTAL_TIME",
"value": 0.07724317
},
{
"statistic": "MAX",
"value": 0.024692496
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"None"
]
},
{
"tag": "method",
"values": [
"POST",
"GET"
]
},
{
"tag": "uri",
"values": [
"/actuator/metrics/{requiredMetricName}",
"/actuator/health",
"/**",
"/hello",
"/"
]
},
{
"tag": "outcome",
"values": [
"CLIENT_ERROR",
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"404",
"200"
]
}
]
}
However I am interested in the metrics for each endpoint / and /hello, information such as average response time, max, min etc.
Is there a configuration parameter for this? Above only provides an aggregate metrics information. I would like to see each endpoints metris.
You can use tags to get aggregated results, for example, if you just want to get metrics for /hello you would request:
/actuator/metrics/http.server.requests?tag=uri:/hello
And you can combine tags, for example if you want to get metrics for all requests made to /hello that returned 200 you could request:
/actuator/metrics/http.server.requests?tag=uri:/hello&tag=status:200

How to link batch-response entries with the request entries in FHIR (DSTU3)

I am currently building an application for which it is important to check the existence of resources with a certain profile.
As we need to check this for 40+ profiles I'd like to put this all in 1 batch request and let our HAPI-FHIR server implementation handle this, as opposed to querying them one by one. This would get too chatty otherwise.
Because I only need to know about whether the resource exists I'd like to use _summary=count. I am assuming this increases the performance of the request.
Example request
{
"resourceType": "Bundle",
"type": "batch",
"entry": [
{
"request": {
"method": "GET",
"url": "/Observation?_profile=http://nictiz.nl/fhir/StructureDefinition/zib-DrugUse&_summary=true"
}
},
{
"request": {
"method": "GET",
"url": "/RelatedPerson?_profile=http://fhir.nl/fhir/StructureDefinition/nl-core-relatedperson&_summary=count"
}
}
]
}
Response
{
"resourceType": "Bundle",
"id": "fd66cfd9-4693-496d-86fc-98289067480b",
"type": "batch-response",
"link": [
{
"relation": "self",
"url": "<redacted>"
}
],
"entry": [
{
"resource": {
"resourceType": "Bundle",
"id": "2647a49f-0503-496b-b274-07d4e9163f1b",
"meta": {
"lastUpdated": "2021-02-15T11:44:18.035+00:00",
"tag": [
{
"system": "http://hl7.org/fhir/v3/ObservationValue",
"code": "SUBSETTED",
"display": "Resource encoded in summary mode"
}
]
},
"type": "searchset",
"total": 48
},
"response": {
"status": "200 OK"
}
},
{
"resource": {
"resourceType": "Bundle",
"id": "2f9cc861-5d20-4da1-aa9f-12153b75539d",
"meta": {
"lastUpdated": "2021-02-15T11:44:18.151+00:00",
"tag": [
{
"system": "http://hl7.org/fhir/v3/ObservationValue",
"code": "SUBSETTED",
"display": "Resource encoded in summary mode"
}
]
},
"type": "searchset",
"total": 10
},
"response": {
"status": "200 OK"
}
}
]
}
Can I assume that the ordering of the batch-response is the same as that of the batch-request?
Or is there a method to annotate the batch entries which are persisted onto the batch-response?
Or finally, is there a flag I can turn on to make the response include the request.url part?
I'm using HAPI-FHIR 5.1.0 both for client and server.
Apparently I didn't look well enough in the specs, as I just found the following:
From the FHIR spec
For a batch, or a successful transaction, the response the server SHALL return a Bundle with type set to batch-response or transaction-response that contains one entry for each entry in the request, in the same order, with the outcome of processing the entry.

How to extend CollectionModel/PagedModel in Spring Hateoas?

A hypermedia response that needs to be consumed by one of my services looks like this:
{
"_embedded": {
"content": [
{
"createdBy": "...",
"createdDate": "2020-03-07T14:21:27.507Z",
"id": "...",
"name": "item1",
"_links": {
"self": {
"href": ".."
}
}
}
]
},
"_links": {
"self": {
"href": "..."
},
},
"pageNumber": 1,
"totalItems": 20,
"pageSize": 10
}
See how the paging related info is not what's expected by Spring Hateoas PagedModel which should have a single "page" property instead of individual ones for pageNumber, totalItems and pageSize:
"page": {
"size": 2,
"totalElements": 1000,
"totalPages": 500,
"number": 5
}
What I did in the end was to extend CollectionModel by adding those individual properties. This does work correctly deserialising a response shown above. But, all the CollectionModel constructors are now deprecated and the alternative is to use "CollectionModel.of", which however returns just CollectionModel.
What's the right way of customising paging information in using Spring Hateoas?
Many thanks!

How to configure Spring Actuator for httptrace and Rest Template?

I have a Spring boot application that it executes several parallel requests, of course, using RestTemplate class.
I configured Spring actuator,to see the Http Trace.
management.endpoints.web.exposure.include=httptrace
When I execute: http://localhost:8080/actuator/httptrace
I see information but related to the request I am doing to my Spring Mvc exposed controllers, but I don't see any info related to the request I am doing internally.
So how can I achieve that? Could you show me some example?
Thanks in advance folks!
You can use Spring Boot /actuator/metrics/http.server.requests to get all endPoints which are executed with their count, exception, outcome, status, total time, etc as follow.
If you want to see details for particular endPoint then you can do it by calling request as follow
localhost:8889/actuator/metrics/http.server.requests?tag=uri:<endPoint>
localhost:8889/actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets
localhost:8889/actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets&tag=status:200
You will get COUNT as how many times particular endPoint has been
called
You will get COUNT as how many times particular endPoint has been
called with a particular Status
To get the average time to execute endPoint you can do
TOTAL_TIME/COUNT for particular endPoint as well as for the whole
application
More Details are Here
localhost:8889/actuator/metrics/http.server.requests
{
"name": "http.server.requests",
"description": null,
"baseUnit": "seconds",
"measurements": [
{
"statistic": "COUNT",
"value": 3
},
{
"statistic": "TOTAL_TIME",
"value": 0.21817219999999998
},
{
"statistic": "MAX",
"value": 0.1379249
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"MethodArgumentTypeMismatchException",
"None"
]
},
{
"tag": "method",
"values": [
"GET"
]
},
{
"tag": "uri",
"values": [
"/{id}.*",
"/user/asset/getAsset/{assetId}",
"/user/asset/getAllAssets"
]
},
{
"tag": "outcome",
"values": [
"CLIENT_ERROR",
"SUCCESS"
]
},
{
"tag": "status",
"values": [
"400",
"404",
"200"
]
}
]
}

How to add http status to all responses dto(data transfer object)?

I've been developing a Spring Boot REST API. I've done so many things so far except my problem. I'm using springfox swagger UI for documentation, and I separated models and dtos for better structure.
I have a base dto model:
public class BaseDto {
private int code;
private boolean success;
public BaseDto() {
this.code = HttpStatus.OK.value();
this.success = HttpStatus.OK.is2xxSuccessful();
}
}
And of course I'm using this class by extending it like:
#ApiModel("User")
public class UserDto extends BaseDto {
private String email;
private String username;
// stuffs
}
If I do user requests when I use this structure, I get:
{
code: 200,
success: true,
email: "",
username: ""
}
and so on... That's fine, but in other dtos, like post model, I have List of UserDto and it's showed in that form. In every object, "code" and "success" fields are written; however, this is not I want to.
The goal that I want to achieve is only once "code" and "success" are written in the response JSON body not all returning list objects.
To clarify more this is Post Dto Model and returns like this:
{
"code": 0,
"createdAt": "2016-05-17T21:59:37.512Z",
"id": "string",
"likes": [
{
"code": 0,
"createdAt": "2016-05-17T21:59:37.512Z",
"deviceType": "string",
"email": "string",
"fbAccessToken": "string",
"fbId": "string",
"followers": [
{}
],
"followings": [
{}
],
"id": "string",
"profileImage": "string",
"success": true,
"token": "string",
"udid": "string",
"updatedAt": "2016-05-17T21:59:37.512Z",
"username": "string",
"version": 0
}
],
"pictures": [
"string"
],
"postedBy": {
"code": 0,
"createdAt": "2016-05-17T21:59:37.512Z",
"deviceType": "string",
"email": "string",
"fbAccessToken": "string",
"fbId": "string",
"followers": [
{}
],
"followings": [
{}
],
"id": "string",
"profileImage": "string",
"success": true,
"token": "string",
"udid": "string",
"updatedAt": "2016-05-17T21:59:37.512Z",
"username": "string",
"version": 0
},
"success": true,
"text": "string",
"updatedAt": "2016-05-17T21:59:37.512Z",
"userId": "string",
"userIds": [
"string"
],
"version": 0
}
You can see at Post Dto model where User Dto is used, code and success fields are added redundant.
I don't know most probably I got wrong approach. Perhaps, I should use adding global HTTP status response to all returning DTOs.
Can anyone help?
You can have an AppUtil class were you can create your response and set HttpStatus. In your AppUtil class write a method like so :
public static ResponseEntity<ResponseEnvelope> successResponse(Object data,
int messageCode, String message) {
ResponseEnvelope envelope = new ResponseEnvelope(data, true, message,
messageCode);
ResponseEntity<ResponseEnvelope> responseEntity = new ResponseEntity<>(
envelope, HttpStatus.OK);
return responseEntity;
}
In the successResponse method you can set your data object in the ResponseEnvelope which along with the HttpStatus will be sent in the ResponseEntity that you want to return.
Check out my previous answer here

Resources