Spring / Spring7 Intermediate to Advanced Interview questions
What is the difference between @RequestMapping's version attribute and content negotiation via the Accept header for API evolution?
The version attribute is a dedicated mechanism built specifically for API lifecycle evolution: it's declared once per handler method, resolved consistently through a configurable, application-wide strategy (header, path segment, query parameter, or media type), understood natively by client-side tooling like RestClient, @HttpExchange, and testing utilities such as RestTestClient, and supports semantic version comparisons - a handler declared with version = "1.2+" matches any request at or above that version, and the framework can surface deprecation signals for older versions automatically.
// dedicated versioning @GetMapping(path = "/products", version = "2") public List<ProductV2> listV2() { } // versioning piggybacked on content negotiation @GetMapping(path = "/products", produces = "application/vnd.company.product.v2+json") public List<ProductV2> listV2ViaMediaType() { }
Content negotiation via the Accept header and the produces attribute is a general-purpose mechanism meant for choosing a representation format - JSON versus XML versus a custom vendor type - and can be repurposed for versioning, as the older application/vnd.company.v1+json convention did, but doing so means hand-building the version-comparison and deprecation logic yourself, and conflates two independent concerns (format and version) into a single header value. Spring Framework 7's native version attribute keeps those concerns cleanly separate: Accept/produces still decides the representation format, while version independently decides which generation of the API handles the request.
More Related questions...