Skip to content

Annotation

Stanislav Molchanovskiy edited this page Nov 15, 2021 · 2 revisions

The interfaces of clients and controllers can be annotated with attributes to describe endpoints and add additional functionality. The following attributes can be used:

Base attributes

The HttpFacade attribute is an equivalent of the ApiControllerAttribute from ASP.NET Core.

[HttpFacade]publicinterfaceIMyController{ ...}

The base URL route for API can be set by the PathAttribute.

[Path("api")]publicinterfaceIMyClient{ ...}

A client interface can be annotated with optional the FacadeAttribute if no other NClient attributes are used in the client interface. It can be useful for improving code readability or for detecting client interfaces if it does not have any other NClient attribute.

[Facade]publicinterfaceIMyClient{ ...}

HTTP methods

Each interface method must have an HTTP attribute that defines the HTTP method for request. There are seven types of such attributes: GetMethodAttribute, HeadMethodAttribute, PostMethodAttribute, PutMethodAttribute, PatchMethodAttribute, DeleteMethodAttribute, OptionsMethodAttribute.

publicinterfaceIMyClient{[GetMethod]Entity[]Get();}

Optionally, you can specify a relative path by passing it to the constructor:

publicinterfaceIMyClient{[GetMethod("entities")]Entity[]Get();}

HTTP parameters

By default, custom type parameters are passed in the request body and primitive type parameters are passed in a URL query. You can explicitly specify how to pass a parameter using attributes: QueryParamAttribute, BodyParamAttribute, HeaderParamAttribute, RouteParamAttribute.

publicinterfaceIMyClient{[PostMethod]voidPost([QueryParam]Entityentity);}

It is also possible to change a parameter name:

publicinterfaceIMyClient{[PostMethod]voidPost([QueryParam(Name="myEntity")]Entityentity);}

Properties

In addition to its main purpose, the QueryParamAttribute allows you to change a property name of a custom object that is passed in URL query:

publicclassEntity{[QueryParam(Name="id")]publicintId}

The same effect will occur if you use the FromQueryAttribute from ASP.NET Core. But in this case you will have a dependency on ASP.NET, which is probably unwanted for client assemblies.

The names of the properties of custom objects that are passed in the request body can be changed using the JsonPropertyNameAttribute:

publicclassEntity{[JsonPropertyName("id")]publicintId}

Static HTTP headers

Use the HeaderAttribute attribute to add a static header. Static headers can be added for all methods:

[Header(Name:"Common-Header",Value:"value")]publicinterfaceIMyClient{ ...}

or for a specific method:

publicinterfaceIMyClient{[GetMethod,Header("Specific-Method-Header",Value:"value")]Entity[]Get();}

Override

The interface methods can be overridden in the inheriting interfaces. Although this is not an override in the usual sense, because you can change the return type of the method:

publicinterfaceIMyController{[GetMethod]Task<int>GetAsync([RouteParam]longid);}publicinterfaceIMyClient:IMyController{[Override]newTask<string>GetFileAsync(longid);}

Overridden methods inherit all method and parameters attributes from the method of the inherited interface. If necessary, you can replace the attributes or add new ones. It is worth noting that multiple inheritance is forbidden if you want to override the method.

Authorization

ASP.NET has two methods for configuring authentication: AuthorizeAttribute and AllowAnonymousAttribute attributes. There are two equivalents in the client: AuthorizedAttribute and AnonymousAttribute.

Response type

The ResponseAttribute is optional attribute that specifies the type of the value and status code returned by the method. This is the equivalent of the ProducesResponseTypeAttribute.

publicinterfaceIMyClient{[GetMethod,Response(typeof(Entity[]),HttpStatusCode.OK)]Entity[]Get();}

Versioning

There are two attributes for API versioning: VersionAttribute and ToVersionAttribute. They are the equivalents of ApiVersionAttribute and MapToApiVersionAttribute from ASP.NET (see ASP.NET API Versioning). They are needed only for controllers and therefore will be ignored when generating the client. Here is an example of their use for the controller interface:

[Version("1.0"),Version("2.0"),Path("api/v{version:apiVersion}")]publicinterfaceIMyController{[GetMethod]Entity[]Get(intid);// Available in versions 1.0 and 2.0[DeleteMethod,ToVersion("2.0")]voidDelete(intid);// Available in version 2.0}

For the client, there is the UseVersionAttribute. You can add it to set the API version for a client:

[UseVersion("1.0"),Path("api/v{version:apiVersion}")]publicinterfaceIMyClient{[GetMethod]Entity[]Get(intid);// Uses version 1.0[DeleteMethod,UseVersion("2.0")]voidDelete(intid);// Uses version 2.0}

The UseVersionAttribute can be used together with the attributes for API versioning, for example:

[UseVersion("1.0")]publicinterfaceIMyClient:IMyController{}

Clone this wiki locally