Support content-based action selection in ASP.NET Core using custom vendor media types. VendorMediaTypes creates a clear path for exposing CQRS through a RESTful API.
Add associations to your endpoint objects to custom media types by decorating those classes with the MediaTypeAttribute.
// ping.cs
[MediaType("application/vnd.ping+json", "application/vnd.health-check+json")]
public class Ping
{
public string Message { get; set; }
}
// detailedping.cs
[MediaType("application/vnd.detailed-ping+json")]
public class DetailedPing
{
public string InstanceId { get; set; }
public string Message { get; set; }
}
While the use of non-canonical media types is a common practice and this package is designed to facilitate that, it is discouraged by RFC 2616 because they are not registered by IANA.
Register VendorMediaTypes in the generic dependency injection container by using AddVendorMediaTypes
on your service collection. This is typically handled in the ConfigureServices
method in your Startup.cs
. By default, the extension method will scan the calling assembly for any classes decorated with [MediaType]
and register them. This behavior can be overriden by manually registering your Type:ContentTypes manually.
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddMvc(options =>
{
//...
});
services.AddVendorMediaTypes(collection =>
{
collection.Add<Ping>("application/vnd.ping+json", "application/vnd.health-check+json");
collection.Add<DetailedPing>("application/vnd.detailed-ping+json");
});
//...
}
On your controller action, decorate the controller action with the ConsumesVendorType
attribute and use the VendorMediaTypeRequest
as the Action parameter. After successful routing, the VendorMediaTypeRequest
can be used to generate the domain model defined in the request.
// GET: api/ping
[HttpPost]
[ConsumesVendorType(typeof(Ping), typeof(DetailedPing))]
public async Task<IActionResult> ExecutePing(VendorMediaTypeRequest request)
{
var query = request.CreateModel();
// ...
}
If you are using Swashbuckle to generate OpenAPI spec and Swagger UI documentation, it is important to use the VendorMediaTypes.Swashbuckle
package to configure Swashbuckle on how to properly render endpoints that use VendorMediaTypes. This is accomplished by using AddSwaggerGenSupport
during registraion.
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddMvc(options =>
{
//...
});
services.AddVendorMediaTypes()
.AddSwaggerGenSupport();
//...
services.AddSwaggerGen(/* ... */);
}
Ali Kheyrollahi's articles/code on 5LMT:
- 5 levels of media type
- Content-based action selection in ASP.NET Web API
- Exposing CQRS Through a RESTful API
MIT