Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing versioning a RESTful API with WCF or ASP.Net Web Api

Assume i've read a lot about versioning a restful api, and I decided to not version the the service through the uri, but using mediatypes (format and schema in the request accept header):

What would be the best way to implement a wcf service or a web api service to serve requests defining the requested resource in the uri, the format (eg. application/json) and the schema/version (eg player-v2) in the accept header?

WCF allows me to route based on the uri, but not based on headers. So I cannot route properly.

Web Api allows me to define custom mediatypeformatters, routing for the requested format, but not the schema (eg. return type PlayerV1 or PlayerV2).

I would like to implement a service(either with WCF or Web Api) which, for this request (Pseudo code):

api.myservice.com/players/123 Accept format=application/json; schema=player-v1

returns a PlayerV1 entity, in json format

and for this request:

api.myservice.com/players/123 Accept format=application/json; schema=player-v2

returns a PlayerV2 entity, in json format.

Any tips on how to implement this?

EDIT: To clarify why I want to use content negotiation to deal with versions, see here: REST API Design: Put the “Type” in “Content-Type”.

like image 539
codeclash Avatar asked May 14 '12 22:05

codeclash


1 Answers

What you are bringing here does not look to me as versioning but it is is more of content negotiation. Accept header expresses wishes of the client on the format of the resource. Server should grant the wishes or return 406. So if we need more of a concept of Contract (although Web API unline RPC does not define one) then using resource is more solid.

The best practices for versioning have yet to be discussed fully but most REST enthusiast believe using the version in the URL is the way to go (e.g. http://server/api/1.0.3/...). This also makes more sense to me since in your approach using content negotiation server has to keep backward compatibility and I can only imagine the code at the server will get more and more complex. With using URL approach, you can make a clean break: old clients can happily use previous while new clients can enjoy the benefits of new API.


UPDATE

OK, now the question has changed to "Implementing content-negotiation in a RESTful AP".

Type 1: Controller-oblivious

Basically, if content negotiation involves only the format of the resource, implementing or using the right media type formatter is enough. For example, if content negotiation involves returning JSON or XML. In these cases, controller is oblivious to content negotiations.

Type 2: Controller-aware

Controller needs to be aware of the request negotiation. In this case, parameters from the request needs to be extracted from the request and passed in as parameter. For example, let's imagine this action on a controller:

public Player Get(string schemaVersion)
{
    ...
}

In this case, I would use classic MVC style value providers (See Brad Wilson's post on ValueProviders - this is on MVC but Web API's value provider looks similar):

public Player Get([ValueProvider(typeof(RequestHeadersSchemaValueProviderFactory))]string schemaVersion)
{
    ...
}
like image 67
Aliostad Avatar answered Oct 16 '22 16:10

Aliostad