How to version model validations for an API?
Why is API versioning necessary at all? It is required for when we want to make some breaking changes to an API endpoint, like stop accepting certain parameters or if we remove some part of the response, which clients, already consuming our API, expect. In that regard it is pretty straight forward how we do this:
- we create a new folder namespace
api/v2
. - we put there the controller, containing the new version of the endpoint
api/v2/controllers/locations_controller.rb
; - we implement our controller action;
- maybe for the response we use a different active model serializer/jBuilder template.
However, what do we do, if we want to change the validation rules for a model? Let's assume, we have a field foo
, which in version 1 of the API, accepts three values a, b and c
. So in the model we have a validaiton like so:
validates :foo, inclusion: { in: %w(a b c) }
Now we want to remove one of the values (a)
and add a new value (d)
. If we just change the validaiton in the model to
validates :foo, inclusion: { in: %w(b c d) }
we'll have at least two problems I can think of:
- If a client of the old endpoint sends value
a
for parameterfoo
they'll get a validation error. - If we update another attribute
bar
of an existing record through the new point, which has valuea
forfoo
(set in the past through the old endpoint), then we'll get a validation error, thatfoo
is not included in the list (which will be quite unexpected, as we updatebar
and don't expect to get any errors forfoo
, which we don't touch at all).
I'd like to hear your thoughts on such problems with API versioning. Thank you.
The reason APIs are versioned is because you can do these validations on the API level rather than in the model. You would say that in v2, we'd ignore the a
parameter now, even if you still submitted it.
I'd recommend checking out some of the Stripe blog posts on API design. They have done a fantastic job of explaining how they do it. https://stripe.com/blog/api-versioning
And Stripe's APIs are by far some of the best designed for handling changes safely that don't break customer apps.