- Notifications
You must be signed in to change notification settings - Fork11
Elixir package that allows to add compatibility layers via API gateways.
License
Nebo15/multiverse
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This plug helps to manage multiple API versions based on request and response gateways. This is an awesome practice to hide your backward compatibility. It allows to have your code in a latest possible version, without duplicating controllers or models. We use it in production.
Inspired by Stripe API. Read more atMOVE FAST, DON'T BREAK YOUR API orAPI versioning.
- reduce changes required to support multiple API versions;
- provide a way to test and schedule API version releases;
- to have minimum dependencies and low performance hit;
- to be flexible enough for most of projects to adopt it.
Multiverse allows you to use a custom adapter which can, for eg.:
- store consumer version upon his first request and re-use it as default each time consumer is using your API, eliminating need of passing version headers for them (a.k.a. version pinning). Change this version when consumer has explicitly set it;
- useother than ISO date version types, eg. incremental counters (
v1
,v2
); - handle malformed versions by responding with JSON errors.
Default adapter works with ISO-8601 date fromx-api-version
header (configurable). For malformed versions it would log a warning and fallback to the default date (configuredvia:default_version
setting):
:first
- apply all gates by default. This option is useful when you integrate Multiverse in existing project and API consumers are not ready to accept latest changes by default;:latest
- user current date as default version. This option is useful when there are no legacy clients or there was no breaking changes before those clients started to send API version.
ISO date adapter allows API clients to use channel name instead of date:
latest
channel would fallback to the current date;edge
channel would disable all changes altogether.
Channels allow you to plan version releases upfront and test them without affecting users,just set future date for a change and pass it explicitly or useedge
channel to test latestapplication version.
The package (take look athex.pm) can be installed as:
- Add
multiverse
to your list of dependencies inmix.exs
:
defdepsdo[{:multiverse,"~> 2.0.0"}]end
- Make sure that
multiverse
is available at runtime in your production:
defapplicationdo[applications:[:multiverse]]end
- Insert this plug into your API pipeline (in your
router.ex
):
pipeline:apidoplug:accepts,["json"]plug:put_secure_browser_headersplugMultiverse,default_version::latestend
- Define module that handles change
defmoduleAccountTypeChangedo@behaviourMultiverse.Changedefhandle_request(%Plug.Conn{}=conn)do# Mutate your request hereIO.inspect"AccountTypeChange.handle_request applied to request"connenddefhandle_response(%Plug.Conn{}=conn)do# Mutate your response hereIO.inspect"AccountTypeChange.handle_response applied to response"connendend
- Enable the change:
pipeline:apidoplug:accepts,["json"]plug:put_secure_browser_headersplugMultiverse,default_version::latest,gates:%{~D[2016-07-21]=>[AccountTypeChange]}end
- Send your API requests with
X-API-Version
header with version lower or equal to2016-07-20
.
You can use any version headers by passing option to Multiverse:
pipeline:apidoplug:accepts,["json"]plug:put_secure_browser_headersplugMultiverse,default_version::latest,version_header:"x-my-version-header",gates:%{~D[2016-07-21]=>[AccountTypeChange]}end
You can use your own adapter which implementsMultiverse.Adapter
behaviour:
pipeline:apidoplug:accepts,["json"]plug:put_secure_browser_headersplugMultiverse,default_version::latest,adapter:MyApp.SmartMultiverseAdapter,gates:%{~D[2016-07-21]=>[AccountTypeChange]}end
- Split your tests into versions:
$ ls -l test/acceptancetotal 0drwxr-xr-x 2 andrew staff 68 Aug 1 19:23 AccountTypeChangedrwxr-xr-x 2 andrew staff 68 Aug 1 19:24 OlderChange
- Avoid touching request or response in old tests. Create API gates and matching folder in acceptance tests.
- Store Multiverse configuration in
config.ex
:
useMix.Configconfig:my_app,MyApp.Endpoint,default_version::latest,gates:%{~D[2016-07-21]=>[AccountTypeChange]}
plugMultiverse,otp_app::my_app,endpoint:__MODULE__
Generate API documentation from changes
@moduledoc
's.Other awesome stuff. Open an issue and tell me about it! :).
SeeLICENSE.md.
About
Elixir package that allows to add compatibility layers via API gateways.