To create REST API companies with Microsoft .NET, the Minimal API was launched with .NET 6. The minimal API makes use of top-level statements and is predicated on some C# language enhancements akin to lambda expression enhancements akin to pure varieties and declaring a return sort. Whereas the minimal API was nice for small service implementations, it acquired some critism with bigger purposes as a result of with this one supply code file was rising too massive. With .NET 7, the minimal API affords new options to resolve all these points as proven on this article.
Minimal API with .NET 6
Let’s begin with .NET 6. With the assistance of the WebApplication
and WebApplicationBuilder
courses, the implementation of the API will be immediately added utilizing top-level statements. With .NET 6, the strategies MapGet
, MapPost
supply new overloads utilizing a Delegate
sort as a substitute of the RequestDelegate
sort. Delegate
, the bottom class of all delegates, permits passing lambda expressions immediately with the parameter. Right here, a characteristic of C# 10 comes into play: enhancements of lambda expressions. Earlier than C# 10, a lambda expression couldn’t be immediately assigned to the Delegate
sort. Both casting the lambda, or creating a brand new occasion of a Func
or Motion
, and assign the lambda to this occasion was required. This didn’t assist with readability. Now you may assign a lambda expression on to the parameter.
The next code snippet (supply file GamesApiDotnet6/Program.cs) exhibits the MapPost
methodology passing a lambda expression with a CreateGameRequest and IGamesService parameters. The CreateGamesRequest comes from the HTTP physique, the IGamesService is injected from the DI container. To reinforce readability (and to resolve circumstances the place the supply can’t be routinely resolved), you may assign attributes akin to [FromServices]
and [FromBody]
to the parameters. With the implementation of the lambda expression, the CreateGameAsync
methodology is invoked, and a CreateGameResponse
is returned. To return outcomes, the manufacturing facility class Outcomes
is out there with .NET 6 to supply returning outcomes just like the ControllerBase
class. The strategies WithName
, Produces
, and WithTags
affect the outcome with the OpenApi description.
To set a transfer of a recreation, one other MapPost
with a distinct route is proven with the subsequent code snippet. This methodology returns Okay
, BadRequest
, NotFound
, or InternalServerError
relying on th eoutcome. Whereas the primary performance of this methodology is applied with the implementation of the IGamesService
contract, the implementation measurement of a single minimal API methodology can simply exceed the scale of a small methodology. Providing a number of API strategies, measurement of Program.cs can develop quick.
Let’s have a look at what will be carried out with .NET 7.
Extension Technique for IEndpointRouteBuilder
Step one to cut back the implementation inside the Program.cs file is to maneuver the implementation of the routes to an extension methodology. This may even be carried out utilizing .NET 6. The extension methodology is outlined in a separate file GameEndpoints.cs. The extension methodology is outlined for the IEndpointRouteBuilder
interface. The MapGameEndpoints
methodology can now be invoked utilizing the WebApplication
occasion named app
, and all of the routes can specified inside the extension methodology MapGameEndpoints
as proven with the MapGet
methodology with the next code snippet.
The MapGameEndpoints
methodology specifies the ILogger
parameter along with the IEndpointRouteBuilder
. The ILogger
parameter permits passing the logging outlined by the ApplicationBuilder
to go it on, and use it inside each route implementation.
Grouping Routes
A number of of the endpoints want frequent performance, akin to authentication, specify tags for OpenAPI, and price limiting. The frequent performance will be specified utilizing the MapGroup
methodology. This methodology returns a RouteGroupBuilder
which in flip can be utilized to specify the routes with the frequent performance. With the pattern code, a gaggle is created with a standard tag and an endpoint filter for logging. Endpoint filters are mentioned later on this article.
Typed Outcomes
With this .NET 6 model of the API you’ve seen a number of invocations of the Produces
methodology to specify the HTTP standing codes that may be returned from an API. This data is used with the OpenAPI description. .NET 7 provides the TypedResults
manufacturing facility sort which is a typed equal of the Outcomes
manufacturing facility sort. Outcomes
is said to return IResult
with each methodology, whereas TypedResults
return a concrete sort, akin to Okay
with the Okay
methodology, and Created
with the Created
methodology. The kinds Okay
and Created
in flip implement IResult
. These typed outcomes assist with unit testing, and routinely add sort metadata to the OpenAPI description.
In case completely different outcomes are returned from a way, one other characteristic of C# 10 comes into play: with the lambda expression, the return sort will be specified. The next code snippet exhibits the lambda expression to create a recreation to return Activity<Outcomes<Created<CreatedGameResponse>, BadRequest>>
. The strategy returns a Activity and makes use of the async
modifier as a result of await
is used with the implementation. The generic sort paramter is of a generic Outcomes
sort. Comparable as you recognize from the Func
, the Motion
, and the ValueTuple
sort, right here a number of generic Outcomes
varieties are outlined with two, three, 4, … as much as six parameters. Every of those parameters has an IResult
constraint which permits solely varieties implementing this interface. Now you can specify the doable returns with out the necessity to add mulitple Produces
strategies. Specifying ‘Outcomes<Created<CreatedGameResponse>, BadRequest>’ signifies that the strategy can return Created
passing a CreatedGameResponseor
BadRequest`.
In case you’ve just one outcome sort, you don’t have to specify the return sort with the lambda expression. Utilizing TypedResults
with the return is all what’s wanted.
Filters
Filters are an effective way so as to add frequent performance endpoint implementations, and to simplify the implementation of the endpoint. Test the next code snippet with the implementation of a recreation transfer. In comparison with the .NET 6 model, the validation of the enter parameter, and the exception dealing with code has been faraway from the implementation of this methodology. Right here, simply the SetMoveAsync methodology utilizing the IGamesService implementation is invoked, and a typed result’s returned. The validation of the enter parameter is completed with the filter GameMoveValidationFilter
, and the exception dealing with is completed with the filter GameMoveExceptionFilter
. The filters are specified utilizing the AddEndpointFilter
methodology.
The implementation of a filter is just like an ASP.NET Core middleware, the time period may very well be middleware for an endpoint.
An endpoint implements the interface IEndpointFilter
with the strategy InvokeAsync
. The strategy InvokeAsync
declares the parameters context
and subsequent
of the categories EndpointFilterInvocationContext
and EndpointFilterDelegate
. Utilizing subsequent
, the filter must invoke the subsequent filter. The ordering of filters delcared is vital: one filter invokes the subsequent one. With the context
, the HttpContext
will be accessed, and the arguments supplied to a route handler.
The following code snippet exhibits the GameMoveValidationFilter
implementation. The InvokeAsync
methodology validates the argument values, and returns a BadRequest
if the validation fails.
GameExceptionFilter
wraps the invocation of the subsequent handler inside a strive/catch. If a GameNotFoundException
exception is caught, the filter returns a NotFound
outcome.
Take away
With .NET 7, the minimal API has been prolonged with a number of options. The IEndpointRouteBuilder
interface affords the MapGroup
methodology to group routes to specify frequent dealing with for endpoint handlers. Filters permit specifying frequent performance, and permit to simplify route handler implementations. Typed outcomes permit to cut back invocations of Produces
. As a substitute of invoking the Produces
methodology, return sorts of the lambda expression implementation will be specifyied utilizing the generic Outcomes
sort along with the TypedResults
manufacturing facility class.
Get pleasure from studying and programming!
Christian
In the event you loved this text, please assist me with a espresso. Thanks!