Reaper.Core
0.1.0-alpha.0.10
See the version list below for details.
dotnet add package Reaper.Core --version 0.1.0-alpha.0.10
NuGet\Install-Package Reaper.Core -Version 0.1.0-alpha.0.10
<PackageReference Include="Reaper.Core" Version="0.1.0-alpha.0.10" />
paket add Reaper.Core --version 0.1.0-alpha.0.10
#r "nuget: Reaper.Core, 0.1.0-alpha.0.10"
// Install Reaper.Core as a Cake Addin #addin nuget:?package=Reaper.Core&version=0.1.0-alpha.0.10&prerelease // Install Reaper.Core as a Cake Tool #tool nuget:?package=Reaper.Core&version=0.1.0-alpha.0.10&prerelease
Reaper
Reaper is a .NET 8+ library and source generator for building Minimal APIs, but not as you know them.
Inspired by the awesome, and more full-featured FastEndpoints, Reaper aims to provide a REPR pattern implementation experience with a focus on performance and simplicity.
Motivation
Minimal APIs are great. They're fast, they're simple, and they're easy to reason about. However trying to separate your endpoints results in a tonne of classes.
FastEndpoints is even better. It's fast (obviously), very well structured, very well documented, and provides a tonne of excellent features out of the box.
But what if you want to sit in the middleground like us? Having FastEndpoints-style REPR endpoint definitions, but with Native AOT, lower runtime overhead, and an even more minimal approach?
That's where we found ourselves whilst building out microservices to be deployed to ACA and looking for a super-simple way to build our endpoints in a pattern that we know and love, with super minimalistic memory footprints and Minimal API performance. For these smaller services, Minimal APIs were a better choice, but we wanted them to be more structured. For larger services, FastEndpoints is still used and is likely a much better choice.
So is Reaper good for you? As with everything in development, it depends.
Getting Started
Reaper only supports .NET 8+.
Add Reaper.Core and Reaper.SourceGenerator from NuGet.
Edit your csproj to allow the generated namespace:
<PropertyGroup>
<InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Reaper.Generated</InterceptorsPreviewNamespaces>
</PropertyGroup>
Add the following to your Program.cs:
builder.UseReaper();
// ... var app = builder.Build(); ...
app.UseReaperMiddleware();
app.MapReaperEndpoints();
Create your first Reaper Endpoint:
public class TestRequest
{
public string Test { get; set; }
}
public class TestResponse
{
public string Input { get; set; }
public DateTime GeneratedAt { get; set; }
}
[ReaperRoute(HttpVerbs.Post, "reflector")]
public class ReflectorEndpoint : ReaperEndpoint<TestRequest, TestResponse>
{
public override async Task<TestResponse> HandleAsync(TestRequest request)
{
return new TestResponse()
{
GeneratedAt = DateTime.UtcNow,
Input = request.Test
};
}
}
Enjoy.
Other Endpoint Bases
Reaper provides a few other endpoint bases for your convenience:
public class NothingEndpoint : ReaperEndpoint { /* Use the HttpContext for anything directly */ }
public class RequestOnlyEndpoint : ReaperEndpointRX<TRequest> { /* Use the Request only */ }
public class ResponseOnlyEndpoint : ReaperEndpointXR<TResponse> { /* Use the Response only */ }
Native AOT Support
The core of Reaper is Native AOT compatible but you'll (currently!) need to use JSON Source Generation on your Request/Response objects. See official guidance on how to do this, and you have to configure the internal Serializer Options to use the context. Essentially, it's what is below, but see the Minimal API Request Delegate Generator Guidance for more.
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(
0, AppJsonSerializerContext.Default);
});
Note that this will be enabled / completed for you automatically in the future.
Implementation
Your Endpoint is injected as a singleton. This means that you should not store any state in your Endpoint (not that you would anyway, right?). Your HandleAsync method is invoked on a per-request basis.
To resolve services
Currently, the HttpContext
is exposed via .Context
within your endpoints.
To resolve services (Scoped or otherwise), simply use:
var svc = Context.RequestServices.GetRequiredService<IMyService>();
What's coming
- Convenience methods for sending responses, where the type is too restrictive
- Ability to bind Request object from route, etc (e.g per-prop
[FromRoute]
) - Automatic (and customisable) Mapper support
- Automatic generation of Source Generatable DTOs (Request/Response)
- More documentation
- Tests, obvs
- More examples
- Support for FluentValidation
- Support for MessagePack
- Support for MemoryPack
Prerelease notice
Reaper is currently in prerelease. It may or may not support everything you need. It may or may not be stable. It may or may not be a good idea to use it in production.
Code is messy right now. What's committed is an early proof of concept. It's not pretty but it works. This will be tidied up in due course.
We are building Reaper alongside our own microservice requirements which are currently running in production. If you have any feedback, please feel free to open an issue or PR.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Reaper.Core:
Package | Downloads |
---|---|
Reaper.Validation
Adds FluentValidation support to Reaper. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.1.0-alpha.0.41 | 64 | 5/18/2024 |
0.1.0-alpha.0.40 | 64 | 1/15/2024 |
0.1.0-alpha.0.39 | 52 | 1/15/2024 |
0.1.0-alpha.0.38 | 67 | 1/14/2024 |
0.1.0-alpha.0.37 | 70 | 1/11/2024 |
0.1.0-alpha.0.32 | 84 | 11/22/2023 |
0.1.0-alpha.0.31 | 75 | 11/22/2023 |
0.1.0-alpha.0.26 | 70 | 11/21/2023 |
0.1.0-alpha.0.21 | 67 | 11/19/2023 |
0.1.0-alpha.0.10 | 88 | 11/18/2023 |
0.1.0-alpha.0.9 | 62 | 11/18/2023 |
0.1.0-alpha.0.8 | 69 | 11/18/2023 |
0.1.0-alpha.0.7 | 67 | 11/17/2023 |
0.1.0-alpha.0.6 | 440 | 11/17/2023 |
0.1.0-alpha.0.5 | 66 | 11/17/2023 |
0.1.0-alpha.0.4 | 63 | 11/17/2023 |
0.1.0-alpha.0.3 | 68 | 11/17/2023 |