Search code examples
swaggerswagger-uispringfox

Springfox global response header


In my spring boot rest API, I'm sending back a unique request id header "x-request-id" for every response (irrespective of the method) for every endpoint. I can add this using something like this:

@ApiResponses(value = { 
    @ApiResponse(
            code = 200, 
            message = "Successful status response", 
            responseHeaders = {
                    @ResponseHeader(
                            name = "x-request-id", 
                            description = "auto generated unique request id", 
                            response = String.class)})
})

This works fine and I can see it in the Swagger UI. However, doing this for every endpoint is a tedious + maintenance problem. I'm looking to do this globally but the Springfox documentation only shows about global response message using .globalResponseMessage option - I can't find anything for global response headers.


Solution

  • Ended up creating an annotation to handle this:

    package com.abc.xyz.api.docs.annotations;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    import io.swagger.annotations.ApiResponse;
    import io.swagger.annotations.ApiResponses;
    import io.swagger.annotations.ResponseHeader;
    
    import com.abc.xyz.api.constants.ApiConstants;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @ApiResponses(value = { 
        @ApiResponse(
                code = 200, 
                message = "Successful status response",
                responseHeaders = {
                        @ResponseHeader(
                                name = ApiConstants.REQUESTIDHEADER,
                                description = ApiConstants.REQUESTIDDESCRIPTION, 
                                response = String.class)}),
        @ApiResponse(
                code = 401, 
                message = "Successful status response",
                responseHeaders = {
                        @ResponseHeader(
                                name = ApiConstants.REQUESTIDHEADER,
                                description = ApiConstants.REQUESTIDDESCRIPTION, 
                                response = String.class)}),
        @ApiResponse(
                code = 403, 
                message = "Successful status response",
                responseHeaders = {
                        @ResponseHeader(
                                name = ApiConstants.REQUESTIDHEADER,
                                description = ApiConstants.REQUESTIDDESCRIPTION, 
                                response = String.class)}),
        @ApiResponse(
                code = 404, 
                message = "Successful status response",
                responseHeaders = {
                        @ResponseHeader(
                                name = ApiConstants.REQUESTIDHEADER,
                                description = ApiConstants.REQUESTIDDESCRIPTION, 
                                response = String.class)}),
        }
    )
    public @interface RequestIdMethod {};
    

    With this, I can add this as a marker annotation in front of my methods:

    @RequestMapping(value = "/heartbeat", method = RequestMethod.GET)
    @RequestIdMethod
    public Heartbeat checkHeartbeat() {
        return new Heartbeat(status);
    }
    

    It is not great because I need to repeat the entire @ApiResponse annotation block for every http return code (obviously there could be other return codes but I only covered the default codes shown by Springfox). Would have been better if there was a way to parameterize the entire @ApiResponse block.