API Versioning in dotnet core - api

I am working on APIs in dotnet core 2.2 and I'd like to version my API.
I'm looking for some solutions except:
Routing method (api/v1/controller, api/v2/contoller)
Routing method using APIVersioning package, (api/v{version: apiVersion}/contoller})
I want to know if there is any other solutions in which I don't have to change the route attribute? I might be completely wrong but can I use middleware? Like, map delegate to map the the incoming requests (based on v1, v2 it carries) to its right controller?
I'll highly appreciate any feedback and suggestions.

You can use the APIVersioning package and configure it so it selects the version based on the HTTP Header.
services.AddApiVersioning(c =>
{
c.ApiVersionReader = new HeaderApiVersionReader("api-version");
}
And then you can use the [ApiVersion] attribute on your controllers.

Can you use custom middleware - yes; however, be advised that endpoint selection is typically much more involved. The routing system provides extension and customization points, which is exactly what API Versioning does for you. Creating your own versioning solution will be a lot more involved than having to add a route template parameter.
If you're going to version by URL segment, then API Versioning requires that you use the ApiVersionRouteConstraint. The default name is registered as apiVersion, but you can change it via ApiVersioningOptions.RouteConstraintName. The route parameter name itself is user-defined. You can use whatever name you want, but version is common and clear in meaning.
Why is a route constraint required at all? API Versioning needs to resolve an API version from the request, but it has no knowledge or understanding of your route templates. For example, how would ASP.NET know that the route parameter id in values/{id:int} has be an integer without the int constraint? Short answer - it doesn't. The API version works the same way. You can compose the route template however you want and API versioning knows how and where to extract the value using the route constraint. What API versioning absolutely does not do is magic string parsing. This is a very intentional design decision. There is no attempt made by API Versioning to try and auto-magically extract or parse the API version value from the request URL. It's also important to note that the v prefix is very common for URL segment versioning, but it's not part of the API version. The approach of using a route constraint negates the need for API Versioning to worry about a v prefix. You can include it in your route template as a literal, if you want to.
If the issue or concern is having to repeatedly include the API version constraint in your route templates, it really isn't any different than including the api/ prefix in every template (which I presume you are doing). It is fairly easy to remain DRY by using one of the following, which could include the prefix api/v{version:apiVersion} for all API routes:
Extend the RouteAttribute and prepend all templates with the prefix; this is the simplest
Roll your own attribute and implement IRouteTemplateProvider
Ultimately, this requirement is yet another consequence of versioning by URL segment, which is why I don't recommend it. URL segment versioning is the least RESTful of all versioning methods (if you care about that) because it violates the Uniform Interface constraint. All other out-of-the-box supported versioning methods do not have this issue.
For clarity, the out-of-the-box supported methods are:
By query string (default)
By header
By media type (most RESTful)
By URL segment
Composition of n methods (ex: query string + header)
You can also create your own method by implementing the IApiVersionReader.
Attributes are just one way that API versions can be applied. In other words, you don't have to use the [ApiVersion] attribute if you don't want to. You can also use the conventions fluent API or create your own IControllerConvention. The VersionByNamespaceConvention is an example of such a convention that derives the API version from the containing .NET namespace. The methods by which you can create and map your own conventions are nearly limitless.

Related

OData or Queryable REST?

Before embarking on API development, looking to choose the right foundation.
So...OData permits queryability over models. Great!
...but REST apis can be decorated with the [Queryable] ...
So... what is the remaining advantage of OData over such Queryable APIs?
Maybe the following are true?
OData routing relies primarily on convention based routing, so not sure one can craft if ever needed to (e.g.: to avoid legacy routes one has to implement?)
Suspect one cannot query REST APIs based on child entities?
Anything else that would come into play?
Thank you!
OData is a specific and standardized implementation of REST. If you make your standard API endpoint's queryable then those specific endpoints will follow most of the OData v4 response conventions but it is up to you to document this for the consumers.
When you choose to start from OData, you are choosing to implement the OData conventional standards for all of the controllers and Entities that you choose to include in the OData Entity Model. This in turn will generate the $metadata document that describes the model and the supported functions and actions.
You can add custom types, functions and actions to an OData controller if you follow the conventions correctly. You can also directly host standard API controller endpoints if you want to, but unless you register them with the OData model, they will not be included in the $metadata document.
You could choose to replicate or implement the entire OData specification in your API from first principals if you want to, including producing your own $metadata document... But if you were going to go to all that trouble then it would have been far easier to just use the ODataController and implement OData properly.
Making the decision to use OData over standard Web API is usually driven by your chosen documentation method and if you can accept the general OData query conventions and if the consumers of the API can understand OData. OData standards are clearly defined so that you don't have to worry as much about educating consumers on how to use your API and can focus more on the implementation itself.

Resource or Restlet

I am using Restlet 2.2.1 and building Rest services. As you know, Router is used to attach either Restlet or Resource as target.
Router router = new Router( getContext() );
router.attach("/healthcheck1",HealthCheckResource.class );
router.attach("/healthcheck2", new HealthCheckRestlet() );
Then you can implement your logic in handle()
Wondering which is best one to use? I know Resource has a very definite life cycle (doInit, handle, release ...) and good place to implement one time logic like initialization.
Attach a ServerResource subclass rather than a Restlet instance when feasible, for a couple of reasons:
Resources are the natural way to structure RESTful APIs. When you use the #Get, #Put, etc. annotations on a resource class, you're effectively documenting that part of your RESTful API, and there are tools that can extract that information to create online documentation automatically. If you use a Restlet instance, its behavior in response to GET, PUT, etc. is not immediately apparent. Ironically, using a Restlet makes it easier to write APIs that are not RESTful.
A separate instance of the resource class is created for each request, meaning that an instance is normally confined to a single thread, which simplifies reasoning about thread-safety. In constrast, the same Restlet instance will be used for all handle(...) calls, potentially leading to complicated thread-safety requirements.
Because each request gets its own resource instance, the resource methods might need to appeal to internal services that are passed via the application context or injected into the resource (see this Restlet extension).
Incidentally, your comment about "one time logic like initialization" might be a misunderstanding. The doInit method is called for each instantiated resource (i.e., once per request for that resource), not one time only.
Note that I'm recommending against directly subclassing Restlet as an end target for a resource URL, except maybe for trivial resources. Using subclasses of Restlet is a different matter: Attaching a Filter which wraps a resource is fine.

Spring Auto REST Docs + Spring Data REST? HATEOAS?

I really like the idea of using Javadoc comments for auto-generating REST Docs!
Huge parts of our REST API are automatically generated by Spring Data REST (by adding #RepositoryRestResource to Repositories). It would be great if REST Docs could also be generated for these - that would be a very high degree of automatition.
But unfortunately most "auto-"snippets are "empty" (e.g. auto-response-fields.adoc only contains a list of links[]-Attributes). I guess the reason could be that the REST Controllers are probably created dynamically by Spring Data REST. Currently I do not see how to re-use the Javadoc comments for them.
Is there any way to auto-generate REST Docs for such REST APIs that are provided by Spring Data REST?
It would even be helpful to manually tell Spring Auto REST Docs which classes are used in requests and responses instead of letting it discover it statically - is that possible?
And we also add HATEOAS "_links" to most response Resources (by providing ResourceProcessors as Beans). These links contain "title"s which are used by Spring REST Docs - if we list all of them with HypermediaDocumentation.linkWithRel(...). This is a bit redundant, and it would be nice if all the _links with "title"s could be processed automatically. (But this can be done by listing all of them in some extra code, so it is not as bad as with Spring Data REST.)
If necessary, I could also create an example project for what I am talking about.
Answer to the question whether one can manually tell Spring Auto REST Docs which classes to use for the documentation:
Spring Auto REST Docs allows to specify the request and response classes to use for the documentation. This can be done with requestBodyAsType and responseBodyAsType. In a test it looks like this:
.andDo(document("folderName",
requestFields().requestBodyAsType(Command.class),
responseFields().responseBodyAsType(CommandResult.class)));
This is from a test in the example project.

What is the difference between a cornice.Service and cornice.resource in Cornice?

I have read through the documentation many times over and search all over for the answer to this question but have come up short. Specifically I've looked at Defining the service and the Cornice API for a service and at Defining resource for resource.
I'm currently building a REST API that will have a similar structure to this:
GET /clients # Gets a list of clients
GET /clients/{id} # Gets a specific client
GET /clients/{id}/users # Gets a specific clients users
What would be the best way to go about this? Should I use a service or a resource or both? And, if both, how?
Resources are high-level convenience, services offer lower level control.
I am just learning cornice myself. Looking at the source code, a Resource creates Services internally, one for the item and one for the collection (if a collection path is specified). The resource also adds views to the services for each method defined with an http verb as the name or in the form collection_[verb].
So there is little difference except that resources are a neat, structured way to define services.
The resource decorator uses a url for the collection, as well as a url pattern for an object.
collection_path=/rest/users
path=/rest/users/{id}
The resource decorator is best used in view classes where you can use get/put/post/delete methods on the objects, as well as collection_get, collection_put, etc. on the collection. I have some examples here:
https://github.com/umeboshi2/trumpet/blob/master/trumpet/views/rest/users.py
Since I make heavy use of the resource decorator and view classes, I haven't found a need for the service function, but it allows you to create get,put,post decorators that wrap view callable functions.
If you are using backbone.js on the client side, the resource decorator and url examples work well with the Backbone collections and models.

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”.
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)
{
...
}