Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API versioning - why aren't models versioned

I've been reading up on all the approaches to version REST APIs. In almost all implementations, controllers and views are versioned, however models are not.

To give the rails example, controllers are organized as:

# app/controllers/api/v1/events_controller.rb
class Api::V1::EventsController < Api::ApiController

end

Corresponding views as put in at different versioned directories as well. Why don't we version models? Is it because we expect our model (underlying database schema) to not change as the API evolves? What happens when I rename a column name in the database and need a new model to account for that?

like image 261
Naya Bonbo Avatar asked Dec 03 '15 20:12

Naya Bonbo


People also ask

Should REST API be versioned?

APIs only need to be up-versioned when a breaking change is made. Breaking changes include: a change in the format of the response data for one or more calls. a change in the request or response type (i.e. changing an integer to a float)

How are rest APIs versioned?

One way to version a REST API is to include the version number in the URI path. xMatters uses this strategy, and so do DevOps teams at Facebook, Twitter, Airbnb, and many more. Major version: The version used in the URI and denotes breaking changes to the API.

Which approaches to versioning does not require the change in the URI?

Versioning using Custom Request Header Version information is specified in the Request Header without the need for any change in the URL. Microsoft uses the request header versioning.


2 Answers

Models are part of the internals of an application, not its public API. When versioning the key is that the input / output does not deviate.

Maintaining different versioned data in the database - eg data that belongs to different versions of an API is not particularly appealing or practical.

So instead you would use adapters / serializers to adapt the input / output to a particular version of your API while the internals run at the current version.

Lets say you have published an API v 1 in a hurry:

GET api/v1/users/:id
  username (String)
  first_name (String)
  lastname (String)

After the release you realize that the naming is inconsistent. So you would create a migration which renames lastname to last_name.

So API version 2 would have the following signature:

GET api/v2/users/:id
  username (String)
  first_name (String)
  last_name (String)

But this should break a test for the API v1 since the response no longer contains lastname.

So to fix it we would create something like:

class Api::V1::UserSerializer < ActiveModel::Serializer
  attributes :username, :first_name, :lastname

  def lastname
    object.last_name
  end
end
like image 128
max Avatar answered Sep 28 '22 09:09

max


Why don't we version models?

Models typically are closely aligned with the database schema. Typically the database is a canonical data store shared by all versions of APIs, hence it does not make much sense to version the models.

Plus, in Rails applications, often the bulk of buisness logic resides in the models. Versioning models would require either replicating the logic or addition of another layer of abstraction which introduces maintenance overhead.

Is it because we expect our model (underlying database schema) to not change as the API evolves?

No. Database schema can and does change very often.

What happens when I rename a column name in the database and need a new model to account for that?

You don't introduce a model to account for schema changes. You adapt the existing model to accomodate the change, and then modify the implementations of prior APIs so the previous version clients continue getting the response in the same format as they expected before.

Since this mapping of your buisness entities (models) to API responses, happens in controllers (or serializers, or json templates - depending on your preferred implementation) -- these parts of your application will have to be modified to ensure backward compatibility.

like image 45
lorefnon Avatar answered Sep 28 '22 08:09

lorefnon