0

So the problem goes like this, for all my REST API endpoints there should be 3 fields always there in my RESPONSE Body like for eg:

{
 "status": "SUCCESS",
 "message": "A list of a recent post",
 "data" : [LIST OF POSTS]
}

or

{
"status" : "NOT_AUTHORIZED",
"message": "User does not have previledge to access this resource",
"errors": ["User does not have Admin access"]
}

So you can get the idea, I want this message status error or data field to be there in all response in my REST API.

Harry Coder
  • 2,429
  • 2
  • 28
  • 32
Sharad Mishra
  • 177
  • 11
  • you can use something like @JsonInclude(JsonInclude.Include.NON_NULL) in your POJO .That way you can only have non-null values in your response. – WannaBeGeek May 13 '19 at 12:17
  • but that's what not I am asking. I want a Response template for all my API endpoints. which have "message", "status" "error"(if there) or "data"(if any) – Sharad Mishra May 13 '19 at 12:30

3 Answers3

2

It could be achieved with a ResponseBodyAdvice:

Allows customizing the response after the execution of an @ResponseBody or a ResponseEntity controller method but before the body is written with an HttpMessageConverter.

Implementations may be registered directly with RequestMappingHandlerAdapter and ExceptionHandlerExceptionResolver or more likely annotated with @ControllerAdvice in which case they will be auto-detected by both.

So you could have something like:

@ControllerAdvice
public class MyResponseBodyAdvisor implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType,
                            Class<? extends HttpMessageConverter<?>> converterType) {

        return converterType.isAssignableFrom(MappingJackson2HttpMessageConverter.class);
    }

    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {

        MyResponseWrapper wrapper = new MyResponseWrapper();
        wrapper.setData(body);
        return wrapper;
    }
}

Where MyResponseWrapper is your class used to wrap the response payload.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
1

You can add a Filter to your project and add these to responses before sending the response.

Follow https://stackoverflow.com/a/41825563/4597596 to create a filter.

Ganesh chaitanya
  • 638
  • 6
  • 18
  • Yes I have seen that post, but there is another problems like exceptions and error are runtimes and message are distinct with each URL endpoints so how do I pass those values to Filter? Is there any good doc over this. – Sharad Mishra May 13 '19 at 12:37
  • I think you can maintain templates for the error messages and success messages as Models. And in Filter code above, check the response status code and append the correct template accordingly as per your requirement. – Ganesh chaitanya May 13 '19 at 12:39
1

You could use ResponseBodyAdvice<T> to globally intercept the response POJO before it is marshalled into JSON, but this seems to be not suitable since each your REST method is supposed to produce distinct messages based on method's functionality. Besides, this would anyway force you to use some wrapper class for responses.

So, I guess, it's better to wrap data (along with status and message) into response manually in each method

Nikolai Shevchenko
  • 7,083
  • 8
  • 33
  • 42