RSCG – immediate.apis

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&#91;&#93;> 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&#91;&#93;>
	{
		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&#91;&#93;> 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&#91;&#93;>
	{

		public HandleBehavior(
		)
		{
		}

		public override async global::System.Threading.Tasks.ValueTask<global::APIDemo.Person&#91;&#93;> 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&#91;&#93;>), 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


Posted

in

,

by

Tags: