0

I am looking to implement Versioning a REST API With Spring Boot and Swagger using Custom Headers. I went through many links like below.

https://dzone.com/articles/versioning-rest-api-with-spring-boot-and-swagger

Spring + Springfox + Header Parameters

Add a header parameter in Swagger UI documentation with Springfox

One thing look clear that my each REST endpoint has to be annotated with Custom Header headers = {"X-API-VERSION=v1"}.

Below is the my sample Rest Endpoints.

@ApiOperation(value = "Find Employees", nickname = "Find Employees")
@ApiResponses(value = { @ApiResponse(code = 200, message = "For Success as well as No Data found scenerio."),
        @ApiResponse(code = 500, message = "Internal Server Error") })
@GetMapping(value = "/employees", headers = {"X-API-VERSION=v1"})
public ResponseEntity<List<Employee>> findEmployees() {
    List<Employee> EmployeeList= employeeservice.findAllEmployees();
    return new ResponseEntity<List<Employee>>(EmployeeList,HttpStatus.OK);
}

Swagger Config changes/updates

@Configuration
@EnableSwagger2
public class SwaggerConfig{
    @Bean
    public Docket api() {
        ParameterBuilder aParameterBuilder = new ParameterBuilder();
        aParameterBuilder.name("X-API-VERSION=v1").modelRef(new ModelRef("string")).parameterType("header").required(true).build();
        List<Parameter> operationParameters = new ArrayList<>();
        operationParameters.add(aParameterBuilder.build());

        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
                .apis(RequestHandlerSelectors.basePackage("com.example"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo())
                .useDefaultResponseMessages(false)
                .globalOperationParameters(operationParameters)
                .globalResponseMessage(
                        RequestMethod.GET,
                        newArrayList(new ResponseMessageBuilder().code(500).message("").build()));
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("API Management")
                .description("Sample Description")
                .termsOfServiceUrl("https://www.test.com")
                .version("0.1")
                .build();
    }
}

As per this link: https://www.springboottutorial.com/spring-boot-versioning-for-rest-services, I must pass value X-API-VERSION=v1, but when I passed that /employees/v1/error endpoint is getting called and nothing has left and no controller is getting called. How to fixed this issue ?

2
  • if you are calling your api from postman is it working fine as per Version specified in Header? Commented Jan 12, 2020 at 5:42
  • I can't figure out what you're doing, what you expect to happen, and what happens instead. Please be precise. You posted a single endpoint, mapped to /employees. How is /employees/v1/error relevant? Commented Jan 12, 2020 at 7:35

1 Answer 1

1

this is how this approach works.

@RestController
public class TestController {


    @RequestMapping(value = "/user")
    public String getUserDefault() {
        return "getUserDefault";
    }

    @RequestMapping(value = "/user", headers = {"X-API-VERSION=v1"})
    public String getUserV1() {
        return "getUserV1";
    }

    @RequestMapping(value = "/user", headers = {"X-API-VERSION=v2"})
    public String getUserV2() {
        return "getUserV2";
    }

}

also, you can use GetMapping instead of RequestMapping, let's test it using curl:

curl --location --request GET 'http://localhost:8080/user' --header 'X-API-VERSION: v2'

return 200 getUserV2

curl --location --request GET 'http://localhost:8080/user' --header 'X-API-VERSION: v1'

return 200 getUserV1

curl --location --request GET 'http://localhost:8080/user'

return 200 getUserDefault
Sign up to request clarification or add additional context in comments.

5 Comments

Looks like we can use both X-API-VERSION: v1 and X-API-VERSION: v2 for a single endpoint ?
@PAA yes in this example I used it 3 times, v1, v2 and without version header
Just to make the use of V2 for example, we need to duplicate the whole code it seems. Can't we utilize under the same code?
@Mojtabye- Do you know how can we set the default Value to Custom Header if Client doesn't send it in the request ?
What if we send more headers in api call then how will it work ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.