The accept version header is an important part of API versioning. It allows clients to specify which version of an API they want to use. The accept header is sent as part of the HTTP request and follows this format:
Accept: application/vnd.{company}.{type}+json; version={version}
For example:
Accept: application/vnd.widgetsinc.v1+json
Why is the accept version header needed?
The accept version header is needed for the following reasons:
- Allows clients to specify which API version they want to use
- Enables servers to handle requests for multiple API versions
- Supports smooth transitions when new API versions are introduced
- Avoids breaking changes for existing clients when APIs evolve
Without an accept header, servers would not know which API version the client expects. The accept header provides an easy way for clients to opt-in to a specific version.
How does the accept version header work?
Here is how the accept version header works in practice:
- Client makes HTTP request to API and includes accept header, e.g. Accept: application/vnd.widgetsinc.v1+json
- Server receives request and checks accept header
- Server uses accept header to determine which API version the client wants
- Server returns response using the requested API version
If the client does not send an accept header or requests an invalid version, the server can return an error or default to the earliest version.
What are the benefits of using accept headers?
Using accept headers for API versioning provides the following key benefits:
- Backwards compatibility – New API versions don’t break existing clients
- Forwards compatibility – Clients can opt-in to new versions at their own pace
- Clear versioning – No confusion over which API version is in use
- Gradual migrations – Smooth transitions to new API versions
- Flexibility – Multiple API versions can co-exist
Overall, accept headers allow APIs to evolve without forcing all clients to upgrade immediately. Client and server changes can be made independently.
What are some examples of accept headers?
Here are some examples of accept version headers:
- Accept: application/vnd.api.v1+json
- Accept: application/vnd.acme.v2+json
- Accept: application/vnd.widgetsinc.v3+json
The core format is application/vnd.{company}.{version}+json. The company and version fields can be customized as needed.
How should API versioning be handled without accept headers?
There are a few other ways to handle API versioning without using accept headers:
- Put the version number in the URL path, e.g. https://api.example.com/v1/users
- Use a custom request header like Api-Version
- Include the version as a parameter, e.g. https://api.example.com/users?version=1
However, these approaches have some downsides compared to using accept headers:
- URL versioning obscures resources and exposes implementation details
- Custom headers don’t leverage existing standards
- Param-based versioning can get unwieldy with many parameters
Accept headers are the cleanest and most robust way to handle API versioning.
What are the limitations of accept headers?
Accept headers have some limitations including:
- Additional header increases request size slightly
- Clients must be updated to send the header
- Caching may be more complex with multiple API versions
- Doesn’t work for HTTP 1.0 or lower
However, these limitations are usually minor compared to the benefits. With standards-based caching and compression, the overhead is negligible.
How are accept headers implemented in popular web frameworks?
Here are some examples of how accept headers are implemented in popular web frameworks:
Django REST Framework
Uses AcceptHeaderVersioning to check accept header and select API version.
REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning' }
Rails
Can check accept headers in controllers before responding.
before_action :check_api_version def check_api_version @version = request.headers['Accept'].scan(/application\/vnd\.myapp\.v(.+)+/).first.first end
Express (Node.js)
Middleware can inspect accept header and load appropriate version.
app.use((req, res, next) => { const version = req.header('Accept').split('/')[1] req.version = version next() })
Conclusion
The accept version header provides an elegant way to handle API versioning. It enables clients to specify the version they want while allowing servers to smoothly evolve APIs over time. Using standards-based accept headers is widely supported across frameworks and avoids many of the downsides of other versioning approaches.