IAppServices conventional routing¶
As previously discussed, our Application layer services (henceforth
IAppServices) can be used as a presentation layer for HTTP based services.
This dynamic Api Controller's presentation layer integrates seamlessly with
ordinary Api Controllers, so developers will always be able to choose the way in
which those services will be exposed and consumed, either by using ordinary or
dynamic auto-generated Api Controllers.
The mechanism behind which said IAppServices are wired as Controllers is
discussed in following sections.
Discovering IAppService implementations¶
Types implementing IAppService will be discovered, registered in DI, and wired
as Api Controllers by the Suite Framework, without any user intervention.
Base route path¶
The Suite Framework will use the same base route path for all IAppService when
building Mvc Routes, said base path can be configured through
EndpointsModuleOptions to suite your needs. By default the value is set to
api, this means that no matter what your entity name is, it will be routed
from that base root path onwards, thus the route built by the Suite Framework
will look like 'api/{YOUR_ENTITY}/{ENTITY_METHOD}.
Routing convention¶
Given an IAppService, the Suite Framework will calculate a valid Mvc Route
for every single public method available. Each IAppService's method will be
given a name, and an http method (verb) constraint, based on its
characteristics. Parameters will also be mapped to QueryString,
Route template, Body or Headers following conventions explained more in
detail in next sections.
Notice
When more than one method's calculated route collides, the Suite Framework will
create a route only mapped to one of the colliding methods. You must be aware
of this situation and choose suitable method names that the Suite Framework  can use
to wire up the IAppService's methods to.
There is a switch in EndpointsModuleOptions that you can use to tell the Suite
Framework to stop and fail, in such cases where the conventional routing isn't
able to map the public IAppService´s methods to valid Mvc routes. By default
the Suite Framework sets the default value to false.
If, for convenience, you want to switch-off the failing behavior, you can
manually set it by injecting EndpointsModuleOptions, and configuring the
module to suite your purposes.
Taking the following IAppService as an example:
the convention pipeline will infer the following endpoints:
- GET rootBasePath/Jobs/AllJobsmapping toGetAllJobsAsync.
- GET rootBasePath/Jobs/JobById/{jobId}mapping toGetJobByIdAsync.
- POST rootBasePath/Jobs/CreateJobmapping toCreateJobAsync.
- POST rootBasePath/Jobs/SearchJobsmapping toSearchJobsAsync.
- PUT rootBasePath/Jobs/UpdateJob/{jobId}mapping toUpdateJobAsync.
Conventions description¶
The different methods exposed on your IAppServices will be discovered and
wired according to the following conventions.
EntityName convention¶
The controller is given a name based on the IAppService's name, removing the
AppService suffix, if any. The Suite Framework will use this entity name not
only to label the controller but also to conform the base path for that entity
to be accessed throughout Mvc scaffolding. If the type being mapped is an
interface, then the leading "I" letter will also be removed.
Notice
To have a good matching between entity name and 'Api Controller Name' when
using Dynamic Api Controller feature it's recommended that application
services are named with an AppService suffix.
For example, given the following IAppService:
| C# | |
|---|---|
The Suite Framework will do these actions:
- Use Jobsas entity name, taking away the leading "I" letter, and trailing "AppService" suffix.
- Map entity to an Api Controller named Jobs.
- Use Jobsas the main root path part for the Api Controller routing feature.
HttpMethod convention¶
Notice
This convention should run pretty early in the convention visitors pipeline.
The HTTPMethod for each member will be assigned mainly based on its name (case
insensitive):
- GET: inferred for methods which name begins with 'Get', 'GetAll' or 'GetList'
- POST: inferred for methods which name begins with 'Post', 'Create', 'Insert', 'Add'. Additionally, if the method has a complex parameter which is not an- specialparameter it will also be assigned an- HTTPMethodof Post.
- PUT: inferred for methods which name begins with 'Put' or 'Update'.
- DELETE: inferred for methods which name begins with 'Delete', 'DeleteMany', or 'Remove'.
- PATCH: inferred for methods which name begins with 'Patch'.
When not matching rule is found, the 'POST' method will be used as default.
Method name¶
Each IAppService's method name will be extracted, and sanitized as follows, to
conform the Mvc Route:
- Remove asyncsuffix, if any.
- Remove verb prefix(Get/Post/Delete), if any.
Please note that should the outcome of the convention applied results in an
empty descriptor, the method name without async prefix will be used as
outcome.
For example, given the following IAppService:
| C# | |
|---|---|
- Getprefix will be removed from method name.
- Asyncsuffix will be removed from method name.
The Mvc Route for that entity's method will be:
- api/Jobs/AllJobs, using- GEThttp method.
Note that the api route path part correspond to the base root path outlined
before.
Parameters convention¶
Depending on the type and purpose of the parameter, it can be placed as route template tokens, request body, query strings or http headers.
Let's dive into the details of how the Suite Framework builds up the Mvc Routing
template addressing the burden of wiring up Mvc Routes binding IAppService's
methods.
'Id' parameters convention¶
If the parameter is named, or ends with "Id", it will be used as part of the template route. For example:
| C# | |
|---|---|
The method GetJobByIdAsync will be reached at the following Mvc Route.
- GET api/Jobs/JobById/{jobId}mapping toGetJobByIdAsync
Pay attention to the '{jobId}' token in the route template. This is the way the Suite Framework builds the route mapping when an 'Id' parameter is present.
Primitive parameters convention¶
When a parameter type is primitive, it will be mapped to the QueryString part
of the Mvc Routing. The exception of this rule is when the parameter is
considered to be an Id parameter, in such cases the convention applied will be
the Id parameter one.
For example, given the following IAppService:
| C# | |
|---|---|
The Suite Framework will build up the following Mvc Route:
- api/Jobs/JobById/{jobId}?param1=SomeValue¶m2=truemapping to- GetJobByIdAsync, with- GETHTTPMethod.
Some things to note here:
- jobIdparameter remains a route element, no matter if it is primitive or not, because it's treated as an- Id parameter.
- param1and- param2are mapped to the- QueryStringrouting path part.
Complex parameters convention¶
Note: complex stands for non-primitive types.
When a parameter type is complex, it will be mapped to the Body part of the
Mvc Routing and the expected Http method will be changed to Post, regardless
of what Verb convention was applied, this condition will overrule any value
defined prior by the convention.
For example, given the following IAppService:
| C# | |
|---|---|
The Suite Framework will build up the following Mvc Route:
- api/Jobs/JobBySomeCriteriamapping to- GetJobBySomeCriteriaAsync, with- POSThttp method and- jobInfoas body parameter.
Please note that even though the IAppService's method could be mapped to GET
http verb, given the GET prefix in its name, the method will be mapped to
POST http verb, because of the complex param type of jobInfo parameter.
Cancellation token convention¶
When a method has a parameter of type CancellationToken our conventions will
bind and configure MVC routing so that said parameter is router the same way it
would if we were using ordinary Api Controllers.
For example, given the following IAppService:
| C# | |
|---|---|
The Suite Framework will build up the following Mvc Route:
- api/Jobs/JobBySomeCriteriamapping to- GetJobBySomeCriteriaAsync, with- POSThttp method and- jobInfoas body parameter. The Cancellation Token parameter will be handled by MVC and it won't be part of the route or parameters in any way whatsoever