RSCG – immediate.apis
name | immediate.apis |
nuget | https://www.nuget.org/packages/immediate.apis/ |
link | https://github.com/immediateplatform/immediate.apis |
author | Stuart Turner |
Defining APIs in classes instead of in minimal API or controllers
This is how you can use immediate.apis .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Immediate.Apis" Version="1.3.0" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> </ItemGroup> <PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> </PropertyGroup> </Project>
The code that you will use is
using APIDemo; var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddAPIDemoHandlers(); var app = builder.Build(); // Configure the HTTP request pipeline. //if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.MapAPIDemoEndpoints(); //app.UseHttpsRedirection(); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); return forecast; }) .WithName("GetWeatherForecast") .WithOpenApi(); app.Run(); internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); }
using Immediate.Apis.Shared; using Immediate.Handlers.Shared; using Microsoft.AspNetCore.Http.HttpResults; namespace APIDemo; [Handler] [MapGet("/users")] public static partial class PersonAPI { public record Query; private static async ValueTask<Person[]> HandleAsync( Query _, CancellationToken token) { await Task.Delay(1000); return new[] { new Person { FirstName = "Ignat", LastName = "Andrei" } }; } }
namespace APIDemo; public class Person { public string? FirstName { get; set; } public string? LastName { get; set; } }
The code that is generated is
using System.Threading; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; #pragma warning disable CS1591 namespace Microsoft.AspNetCore.Builder { public static partial class APIDemoRoutesBuilder { private static void MapAPIDemo_PersonAPIEndpoint(IEndpointRouteBuilder app) { var endpoint = app .MapGet( "/users", async ( [AsParameters] global::APIDemo.PersonAPI.Query parameters, [FromServices] global::APIDemo.PersonAPI.Handler handler, CancellationToken token ) => { var ret = await handler.HandleAsync(parameters, token); return ret; } ); } } } namespace APIDemo { /// <remarks><see cref="global::APIDemo.PersonAPI.Query" /> registered using <c>[AsParameters]</c></remarks> partial class PersonAPI; }
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; #pragma warning disable CS1591 namespace Microsoft.AspNetCore.Builder; public static partial class APIDemoRoutesBuilder { public static IEndpointRouteBuilder MapAPIDemoEndpoints( this IEndpointRouteBuilder app ) { MapAPIDemo_PersonAPIEndpoint(app); return app; } }
using Microsoft.Extensions.DependencyInjection; #pragma warning disable CS1591 namespace APIDemo; partial class PersonAPI { public sealed partial class Handler : global::Immediate.Handlers.Shared.IHandler<global::APIDemo.PersonAPI.Query, global::APIDemo.Person[]> { private readonly global::APIDemo.PersonAPI.HandleBehavior _handleBehavior; public Handler( global::APIDemo.PersonAPI.HandleBehavior handleBehavior ) { var handlerType = typeof(PersonAPI); _handleBehavior = handleBehavior; } public async global::System.Threading.Tasks.ValueTask<global::APIDemo.Person[]> HandleAsync( global::APIDemo.PersonAPI.Query request, global::System.Threading.CancellationToken cancellationToken = default ) { return await _handleBehavior .HandleAsync(request, cancellationToken) .ConfigureAwait(false); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] public sealed class HandleBehavior : global::Immediate.Handlers.Shared.Behavior<global::APIDemo.PersonAPI.Query, global::APIDemo.Person[]> { public HandleBehavior( ) { } public override async global::System.Threading.Tasks.ValueTask<global::APIDemo.Person[]> HandleAsync( global::APIDemo.PersonAPI.Query request, global::System.Threading.CancellationToken cancellationToken ) { return await global::APIDemo.PersonAPI .HandleAsync( request , cancellationToken ) .ConfigureAwait(false); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] public static IServiceCollection AddHandlers( IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Scoped ) { services.Add(new(typeof(global::APIDemo.PersonAPI.Handler), typeof(global::APIDemo.PersonAPI.Handler), lifetime)); services.Add(new(typeof(global::Immediate.Handlers.Shared.IHandler<global::APIDemo.PersonAPI.Query, global::APIDemo.Person[]>), typeof(global::APIDemo.PersonAPI.Handler), lifetime)); services.Add(new(typeof(global::APIDemo.PersonAPI.HandleBehavior), typeof(global::APIDemo.PersonAPI.HandleBehavior), lifetime)); return services; } }
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; #pragma warning disable CS1591 namespace APIDemo; public static class HandlerServiceCollectionExtensions { public static IServiceCollection AddAPIDemoBehaviors( this IServiceCollection services) { return services; } public static IServiceCollection AddAPIDemoHandlers( this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Scoped ) { global::APIDemo.PersonAPI.AddHandlers(services, lifetime); return services; } }
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/immediate.apis