0

We are using Zuul, Eureka and spring boot application services for REST APIs.

Suppose my spring boot service is down and when I tried to access the API using Zuul API gateway, I am getting ZuulException and response is below :

{
    "timestamp": "2018-10-12T14:29:09.632+0000",
    "status": 500,
    "error": "Internal Server Error",
    "exception": "com.netflix.zuul.exception.ZuulException",
    "message": "GENERAL"
}

I want to customize the response format like below:

{
    "success": false,
    "message": "Service is down. Please try later"
}

I tried to implement https://stackoverflow.com/a/39841785/5506061 but its not working for me.

Please suggest how to customize the response for ZuulException.

Krish
  • 1,804
  • 7
  • 37
  • 65

1 Answers1

0

You can implement your own FallbackProvider and customize the response based on the cause if needed.

Something like :

@Component
public class CustomFallbackBasedOnCause implements FallbackProvider {

private static final String DEFAULT_MSG = "{\"success\": false,\"message\": \"Service is down. Please try later\"}";

@Override
public String getRoute() {
    return "*"; // * = all routes
}

@Override
public ClientHttpResponse fallbackResponse(final Throwable cause) {
    if (cause instanceof HystrixTimeoutException) {
        return response(HttpStatus.GATEWAY_TIMEOUT);
    } else {
        return fallbackResponse();
    }
}

@Override
public ClientHttpResponse fallbackResponse() {
    return response(HttpStatus.INTERNAL_SERVER_ERROR);
}

private ClientHttpResponse response(final HttpStatus status) {
    return new ClientHttpResponse() {
        @Override
        public HttpStatus getStatusCode() throws IOException {
            return status;
        }

        @Override
        public int getRawStatusCode() throws IOException {
            return status.value();
        }

        @Override
        public String getStatusText() throws IOException {
            return status.getReasonPhrase();
        }

        @Override
        public void close() {
        }

        @Override
        public InputStream getBody() throws IOException {
            return new ByteArrayInputStream(DEFAULT_MSG.getBytes());
        }

        @Override
        public HttpHeaders getHeaders() {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            return headers;
        }
    };
}
}

As you can see in the getRoute() method, you can specify if this customFallback will be used for all routes (return "*") or for a specific route.

In case you work with Registry service (e.g Eureka). You don’t specify the route URL but the service id instead. return "SERVICEID"

redoff
  • 1,124
  • 11
  • 18