### Configure Endpoint with Shorthand Route Source: https://fast-endpoints.com/docs/misc-conveniences Use shorthand methods like Get(), Post(), etc., to configure verbs and routes in a more concise way. This example configures a GET endpoint for a specific customer ID route. ```csharp public override void Configure() { Get("/api/customer/{CustomerID}"); } ``` -------------------------------- ### Configure Endpoint Options Source: https://fast-endpoints.com/docs/misc-conveniences Customize endpoint registration and setup using the Options() method. This example configures CORS policies, requires a specific host, and sets a default problem response for 404 errors. ```csharp Options(b => b.RequireCors(x => x.AllowAnyOrigin()) .RequireHost("domain.com") .ProducesProblem(404)); ``` -------------------------------- ### Install FastEndpoints.AspVersioning Package Source: https://fast-endpoints.com/docs/api-versioning Install the necessary wrapper library from NuGet using the Package Manager Console. ```powershell Install-Package FastEndpoints.AspVersioning ``` -------------------------------- ### Install FastEndpoints Template Pack Source: https://fast-endpoints.com/docs/scaffolding Install the FastEndpoints .NET new item template pack using the dotnet CLI. ```bash dotnet new install FastEndpoints.TemplatePack ``` -------------------------------- ### Multiple Request Examples Source: https://fast-endpoints.com/docs/swagger-support Specify multiple request examples by setting ExampleRequest multiple times or by adding to the RequestExamples collection. ```csharp Summary(s => { s.ExampleRequest = new MyRequest {...}; s.ExampleRequest = new MyRequest {...}; s.RequestExamples.Add(new(new MyRequest { ... })); s.RequestExamples.Add(new(new MyRequest { ... }, "Example Label")); }); ``` -------------------------------- ### Install and Scaffold FastEndpoints Template Pack Source: https://fast-endpoints.com/docs/integration-unit-testing Installs the FastEndpoints template pack and scaffolds a new project for end-to-end testing walkthrough. ```bash dotnet new install FastEndpoints.TemplatePack dotnet new feproj -n E2EWalkthrough ``` -------------------------------- ### Example Server Log Entry Source: https://fast-endpoints.com/docs/exception-handler This is an example of a server log entry generated by the default exception handler middleware. ```csharp fail: FastEndpoints.ExceptionHandler[0] ================================= HTTP: POST /inventory/adjust-stock TYPE: JsonException REASON: 'x' is an invalid start of a value. Path: $.ValMin | LineNumber: 4... --------------------------------- at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state,... at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader,... at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter,... ... ``` -------------------------------- ### Create Project and Install FastEndpoints Source: https://fast-endpoints.com/docs Initializes a new .NET web project and adds the FastEndpoints package. ```bash dotnet new web -n MyWebApp cd MyWebApp dotnet add package FastEndpoints ``` -------------------------------- ### Basic Swagger Setup in Program.cs Source: https://fast-endpoints.com/docs/swagger-support Add Swagger support to your FastEndpoints application by including these lines in your program's startup configuration. ```csharp using FastEndpoints; using FastEndpoints.Swagger; //add this var bld = WebApplication.CreateBuilder(); bld.Services .AddFastEndpoints() .SwaggerDocument(); //define a swagger document var app = bld.Build(); app.UseFastEndpoints() .UseSwaggerGen(); //add this app.Run(); ``` -------------------------------- ### Install FastEndpoints.Swagger Package Source: https://fast-endpoints.com/docs/swagger-support Install the necessary NuGet package to enable Swagger support in your FastEndpoints project. ```bash dotnet add package FastEndpoints.Swagger ``` -------------------------------- ### Install FastEndpoints.ClientGen.Kiota Package Source: https://fast-endpoints.com/docs/swagger-support Command to add the Kiota client generation package to your project. ```bash dotnet add package FastEndpoints.ClientGen.Kiota ``` -------------------------------- ### Install FastEndpoints.Generator NuGet Package Source: https://fast-endpoints.com/docs/dependency-injection Install the FastEndpoints.Generator package via the .NET CLI to enable source-generated service registrations. ```bash dotnet add package FastEndpoints.Generator ``` -------------------------------- ### Install Job Queues NuGet Package Source: https://fast-endpoints.com/docs/job-queues Install the FastEndpoints.JobQueues NuGet package if you are using job queues independently of the main FastEndpoints library. ```bash dotnet add package FastEndpoints.JobQueues ``` -------------------------------- ### Scaffold Bare-Bones Starter Project Source: https://fast-endpoints.com/docs/scaffolding Creates a new FastEndpoints starter project with a traditional integration testing setup using xUnit. Use this for a basic project structure. ```bash dotnet new feproj -n MyAwesomeProject ``` -------------------------------- ### Install FastEndpoints Template Pack Source: https://fast-endpoints.com/docs/scaffolding Installs the FastEndpoints template pack globally, enabling the use of FastEndpoints project scaffolding commands. ```bash dotnet new install FastEndpoints.TemplatePack ``` -------------------------------- ### Install FastEndpoints.Messaging NuGet Package Source: https://fast-endpoints.com/docs/command-bus Command to add the FastEndpoints.Messaging package to your project. ```bash dotnet add package FastEndpoints.Messaging ``` -------------------------------- ### Swagger Docs Structure Example Source: https://fast-endpoints.com/docs/api-versioning Illustrates the hierarchical structure of Swagger documentation across different release versions. ```text Swagger Docs ├── Initial Release │ ├── /user/delete │ └── /user/profile ├── Release 1 │ ├── /user/delete/v1 │ └── /user/profile/v1 └── Release 2 ├── /user/delete/v1 └── /user/profile/v2 ``` -------------------------------- ### Associate Endpoints with Version Sets Source: https://fast-endpoints.com/docs/api-versioning Map endpoints to specific version sets and API versions. This example shows how to configure GET endpoints for different versions of the 'Orders' API. ```csharp public class GetInvoices_v1 : EndpointWithoutRequest { public override void Configure() { Get("/orders/invoices"); Options(x => x .WithVersionSet(">>") .MapToApiVersion(1.0)); } public override async Task HandleAsync(CancellationToken c) { await Send.OkAsync("v1 - orders"); } } public class GetInvoices_v2 : EndpointWithoutRequest { public override void Configure() { Get("/order/invoices"); Options(x => x .WithVersionSet(">>") .MapToApiVersion(2.0)); } public override async Task HandleAsync(CancellationToken c) { await Send.OkAsync("v2 - orders"); } } ``` -------------------------------- ### Configure Endpoint Summary and Descriptions Source: https://fast-endpoints.com/docs/swagger-support Use the Summary() method to set endpoint summaries, descriptions, request examples, and response examples for different status codes. ```csharp public override void Configure() { Post("/item/create"); Description(b => b.Produces(403)); Summary(s => { s.Summary = "short summary goes here"; s.Description = "long description goes here"; s.ExampleRequest = new MyRequest {...}; s.ResponseExamples[200] = new MyResponse {...}; s.Responses[200] = "ok response description goes here"; s.Responses[403] = "forbidden response description goes here"; }); } ``` -------------------------------- ### Example Idempotent GET Request with Curl Source: https://fast-endpoints.com/docs/idempotency Send a GET request to an idempotent endpoint with the 'Idempotency-Key' header containing a unique value for each distinct request. ```curl curl -X 'GET' \ 'http://localhost:5000/my-endpoint' \ -H 'accept: text/plain' \ -H 'idempotency-key: 1dc3d9a8527047069f8056175a71fe79' ``` -------------------------------- ### Install FastEndpoints Template Pack and Scaffold AOT Project Source: https://fast-endpoints.com/docs/native-aot Use the dotnet CLI to install the template pack and scaffold a new FastEndpoints project configured for AOT publishing. ```bash dotnet new install FastEndpoints.TemplatePack dotnet new feaot -n MyProject ``` -------------------------------- ### Example JSON Response Source: https://fast-endpoints.com/docs/exception-handler This is an example of the JSON response returned to the client when an internal server error occurs. ```json { "Status": "Internal Server Error!", "Code": 500, "Reason": "'x' is an invalid start of a value. Path: $.ValMin | LineNumber: 4...", "Note": "See application log for stack trace." } ``` -------------------------------- ### Configure Swagger and FastEndpoints in program.cs Source: https://fast-endpoints.com/docs/native-aot This snippet shows how to configure FastEndpoints and SwaggerDocument in the program.cs file for a simplified setup during development. ```csharp var bld = WebApplication.CreateSlimBuilder(args); bld.Services .AddFastEndpoints(...) .SwaggerDocument( o => o.DocumentSettings = d => { d.DocumentName = "v1"; }); var app = bld.Build(); app.UseFastEndpoints(...) .UseOpenApi(c => c.Path = "/openapi/{documentName}.json"); app.MapScalarApiReference(o => o.AddDocument("v1")); app.Run(); ``` -------------------------------- ### Install Native AOT Dependencies on Linux (Arch) Source: https://fast-endpoints.com/docs/native-aot Install the required dependencies for Native AOT compilation on Arch Linux. ```bash # Arch sudo pacman -S --needed base-devel clang zlib krb5 icu ``` -------------------------------- ### Install Native AOT Dependencies on Linux (Alpine) Source: https://fast-endpoints.com/docs/native-aot Install the required dependencies for Native AOT compilation on Alpine Linux. ```bash # Alpine apks add clang build-base zlib-dev ``` -------------------------------- ### Example POST Request Body Source: https://fast-endpoints.com/docs Sample JSON payload to send to the /api/user/create endpoint. ```json { "FirstName": "Marlon", "LastName": "Brando", "Age": 40 } ``` -------------------------------- ### Add FastEndpoints.Messaging Package Source: https://fast-endpoints.com/docs/event-bus Install the messaging library using the dotnet CLI to use the Event Bus independently. ```bash dotnet add package FastEndpoints.Messaging ``` -------------------------------- ### Example Response Body Source: https://fast-endpoints.com/docs Expected JSON response after a successful POST request. ```json { "FullName": "Marlon Brando", "IsOver18": true } ``` -------------------------------- ### Install Native AOT Dependencies on Linux (Fedora/RHEL) Source: https://fast-endpoints.com/docs/native-aot Install the required dependencies for Native AOT compilation on Fedora or RHEL-based Linux distributions. ```bash # Fedora/RHEL sudo dnf install clang zlib-devel zlib-ng-devel zlib-ng-compat-devel ``` -------------------------------- ### Install Native AOT Dependencies on Linux (Debian) Source: https://fast-endpoints.com/docs/native-aot Install the required dependencies for Native AOT compilation on Debian-based Linux distributions. ```bash # Debian sudo apt-get install clang zlib1g-dev ``` -------------------------------- ### Example HTTP Request and DTO Source: https://fast-endpoints.com/docs/model-binding Demonstrates how an HTTP request with a route parameter and a JSON body is bound to a DTO. Route parameters have higher priority than JSON body. ```http route: /api/user/{UserID} url: /api/user/54321 json: { "UserID": "12345" } ``` ```csharp public class GetUserRequest { public string UserID { get; set; } } ``` -------------------------------- ### Auto-Generated Permission Class Example Source: https://fast-endpoints.com/docs/security An example of a permission class automatically generated by the source generator. The permission codes are hashes of the permission names. ```csharp public static partial class Allow { public const string Article_Create = "7OR"; public const string Article_Approve = "LVN"; public const string Article_Reject = "ZTT"; } ``` -------------------------------- ### Configure Versioning Middleware Source: https://fast-endpoints.com/docs/api-versioning Enable the versioning middleware in your application's service configuration. This example sets the default API version and specifies header-based version reading. ```csharp bld.Services .AddFastEndpoints() .AddVersioning(o => { o.DefaultApiVersion = new(1.0); o.AssumeDefaultVersionWhenUnspecified = true; o.ApiVersionReader = new HeaderApiVersionReader("X-Api-Version"); }) ``` -------------------------------- ### Endpoint with EmptyRequest and EmptyResponse Source: https://fast-endpoints.com/docs Example of an endpoint that does not expect a request body and does not return a response body. ```csharp public class MyEndpoint : Endpoint { } ``` -------------------------------- ### Configure and Use Event Bus in Console App Source: https://fast-endpoints.com/docs/event-bus Register messaging services and use the event bus in a console application. Includes example event and handler. ```csharp using FastEndpoints; //add this using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; var bld = Host.CreateApplicationBuilder(); bld.Services.AddMessaging(); //add this var host = bld.Build(); host.Services.UseMessaging(); //add this var appStartedEvent = new AppStarted(); await appStartedEvent.PublishAsync(); await host.RunAsync(); sealed class AppStarted : IEvent { public string Message => "Welcome to the App!"; } sealed class AppStartedHandler(ILogger logger) : IEventHandler { public Task HandleAsync(AppStarted e, CancellationToken c) { logger.LogInformation("{@msg}", e.Message); return Task.CompletedTask; } } ``` -------------------------------- ### Define Endpoint Starting Release Version Source: https://fast-endpoints.com/docs/api-versioning Configures an endpoint to be included in Swagger documentation starting from a specific release version. If not specified, it defaults to the endpoint's own version. ```csharp public override void Configure() { Version(1).StartingRelease(2); } ``` -------------------------------- ### Mark Endpoint with Version 2 Source: https://fast-endpoints.com/docs/api-versioning Assign a specific version to an endpoint by calling the 'Version(n)' method in its Configure method. This example marks the 'AdminLoginEndpoint_V2' as version 2. ```csharp public class AdminLoginEndpoint_V2 : Endpoint { public override void Configure() { Get("admin/login"); Version(2); } } ``` -------------------------------- ### Setup gRPC Server for Event Hub Source: https://fast-endpoints.com/docs/remote-procedure-calls Configure a gRPC server to host an event hub for a specific event type. Ensure the server listens on the correct port and protocol. ```csharp var bld = WebApplication.CreateBuilder(); bld.WebHost.ConfigureKestrel(o => o.ListenLocalhost(6000, o => o.Protocols = HttpProtocols.Http2)); bld.AddHandlerServer(); var app = bld.Build(); app.MapHandlers(h => { h.RegisterEventHub(); }); app.Run() ``` -------------------------------- ### Adding FastEndpoints Messaging Services Source: https://fast-endpoints.com/docs/command-bus Installs and registers the messaging library services for standalone use in a console application. ```csharp using FastEndpoints; //add this using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; var bld = Host.CreateApplicationBuilder(); bld.Services.AddMessaging(); //add this var host = bld.Build(); host.Services.UseMessaging(); //add this var greetUser = new GreetUser(); await greetUser.ExecuteAsync(); await host.RunAsync(); sealed class GreetUser : ICommand { public string Message => "Welcome to the App!"; } sealed class GreetUserHandler(ILogger logger) : ICommandHandler { public Task ExecuteAsync(GreetUser e, CancellationToken c) { logger.LogInformation("{@msg}", e.Message); return Task.CompletedTask; } } ``` -------------------------------- ### JobStorageProvider Implementation for Results Source: https://fast-endpoints.com/docs/job-queues Implement IJobStorageProvider and IJobResultProvider to handle storing and retrieving job results. This involves interacting with the job entity to set and get results. ```csharp sealed class JobStorageProvider : IJobStorageProvider, IJobResultProvider { ... public Task StoreJobResultAsync(Guid trackingId, TResult result, CancellationToken ct) { // 1.) retrieve the job by trackingId. // 2.) set the result on the job like so: ((IJobResultStorage)job).SetResult(result); // 3.) persist the job entity back to the database. } public Task GetJobResultAsync(Guid trackingId, CancellationToken ct) { // 1.) retrieve the job by trackingId. // 2.) extract the result from the job like so: var result = ((IJobResultStorage)job).GetResult(); // 3.) return the result } } ``` -------------------------------- ### Prepare Startup Configuration Source: https://fast-endpoints.com/docs Configures the application services and middleware for FastEndpoints in Program.cs. ```csharp using FastEndpoints; var bld = WebApplication.CreateBuilder(); bld.Services.AddFastEndpoints(); var app = bld.Build(); app.UseFastEndpoints(); app.Run(); ``` -------------------------------- ### Filter Endpoint Registration by Verb and Route Source: https://fast-endpoints.com/docs/configuration-settings Prevent specific endpoints from being registered during startup by providing a filtering function. This example prevents GET requests to '/api/mobile/test'. ```csharp app.UseFastEndpoints(c => { c.Endpoints.Filter = ep => { if (ep.Verbs.Contains("GET") && ep.Routes.Contains("/api/mobile/test")) { return false; // don't register this endpoint } return true; }; }); ``` -------------------------------- ### Create New Web Project and Add FastEndpoints Packages Source: https://fast-endpoints.com/docs/native-aot Create a new ASP.NET Core web project and add the necessary FastEndpoints NuGet packages. ```bash dotnet new web -n MyWebApp cd MyWebApp dotnet add package FastEndpoints dotnet add package FastEndpoints.Generator dotnet add package FastEndpoints.Swagger dotnet add package Scalar.AspNetCore ``` -------------------------------- ### Login Endpoint for JWT Refresh Tokens Source: https://fast-endpoints.com/docs/security Create a user login endpoint that checks credentials and issues access and refresh tokens. This example uses `CreateTokenWith()` to generate the token pair. ```csharp public class LoginEndpoint : EndpointWithoutRequest { public override void Configure() { Get("/api/login"); AllowAnonymous(); } public override async Task HandleAsync(CancellationToken c) { //user credential checking has been omitted for brevity Response = await CreateTokenWith("user-id-001", u => { u.Roles.AddRange(new[] { "Admin", "Manager" }); u.Permissions.Add("Update_Something"); u.Claims.Add(new("UserId", "user-id-001")); }); } } ``` -------------------------------- ### C# Server-Sent Events with Multiple Data Types Source: https://fast-endpoints.com/docs/server-sent-events Send different types of data within a single Server-Sent Events stream using the StreamItem wrapper. This example alternates between sending string data and GUID data based on the second. ```csharp public override async Task HandleAsync(CancellationToken c) { await Send.EventStreamAsync(GetMultiDataStream(c), c); async IAsyncEnumerable GetMultiDataStream([EnumeratorCancellation] CancellationToken ct) { long id = 0; while (!ct.IsCancellationRequested) { await Task.Delay(1000); id++; if (DateTime.Now.Second % 2 == 1) yield return new StreamItem(id.ToString(), "odd-second", Guid.NewGuid()); //guide data else yield return new StreamItem(id.ToString(), "even-second", "hello!"); //string data } } } ``` -------------------------------- ### Generate FastEndpoints Project from OpenAPI Source: https://fast-endpoints.com/docs/scaffolding Uses the OpenAPI Generator CLI tool to create a FastEndpoints server project from a specified OpenAPI document. Ensure the tool is installed first. ```bash openapi-generator-cli generate \ --generator-name aspnet-fastendpoints \ --input-spec d:/my_open_api_file.yaml \ --output d:/my_fastendpoints_project ``` -------------------------------- ### FastEndpoints Feature Fileset Help Source: https://fast-endpoints.com/docs/scaffolding Displays the available options for the `dotnet new feat` command, including attributes, mapper, validator, HTTP method, and route configuration. ```bash > dotnet new feat --help FastEndpoints Feature Fileset (C#) Options: -t|--attributes Whether to use attributes for endpoint configuration bool - Optional Default: false -p|--mapper Whether to use a mapper bool - Optional Default: true -v|--validator Whether to use a validator bool - Optional Default: true -m|--method Endpoint HTTP method GET POST PUT DELETE PATCH Default: GET -r|--route Endpoint path string - Optional Default: api/route/here ``` -------------------------------- ### Configure Job Queues in Startup Source: https://fast-endpoints.com/docs/job-queues Enable job queues by configuring services and middleware during application startup. This involves adding job queues and their storage provider. ```csharp var bld = WebApplication.CreateBuilder(); bld.Services .AddFastEndpoints() .AddJobQueues(); //ignore generic arguments for now var app = bld.Build(); app.UseFastEndpoints(); app.UseJobQueues(); app.Run(); ``` -------------------------------- ### Setting up Pre-configured Clients on Fixture Source: https://fast-endpoints.com/docs/integration-unit-testing Set up pre-configured clients on the AppFixture class itself if they will be consistently used across multiple test methods. Ensure proper disposal in TearDownAsync. ```csharp public class MyApp : AppFixture { public HttpClient Admin { get; private set; } public HttpClient Customer { get; private set; } protected override async ValueTask SetupAsync() { var apiKey = await GetApiKey(...); Admin = CreateClient(c => c.DefaultRequestHeaders.Add("x-api-key", apiKey)); Customer = CreateClient(); } protected override ValueTask TearDownAsync() { Admin.Dispose(); Customer.Dispose(); return ValueTask.CompletedTask; } } ``` -------------------------------- ### Build Project for Generator Source: https://fast-endpoints.com/docs/model-binding Perform an initial build after enabling source generation. This step allows the generator to run and create the necessary serializer contexts. ```bash dotnet build ``` -------------------------------- ### Deprecate Endpoint with Starting Release Version Source: https://fast-endpoints.com/docs/api-versioning Combines defining a starting release version with deprecating an endpoint at a future release version. ```csharp public override void Configure() { Version(1) .StartingRelease(2) .DeprecateAt(4); } ``` -------------------------------- ### Enable Versioning with Prefix Source: https://fast-endpoints.com/docs/api-versioning Enable versioning by setting the 'Prefix' option during application startup. This adds a prefix like 'v' before the version number in the route. ```csharp app.UseFastEndpoints(c => { c.Versioning.Prefix = "v"; }); ``` -------------------------------- ### Run App to Generate Clients Source: https://fast-endpoints.com/docs/swagger-support Command to execute the application and trigger API client generation. ```bash cd MyApp dotnet run --generateclients true ``` -------------------------------- ### RFC7807 & RFC9457 Compatible Problem Details Example Source: https://fast-endpoints.com/docs/configuration-settings Example of an RFC-compliant problem details JSON response. This format is used for standardized error reporting. ```json { "type": "https://www.rfc-editor.org/rfc/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "instance": "/api/test/666", "traceId": "0HMPNHL0JHL76:00000001", "errors": [ { "name": "clientIP", "reason": "IP address is blocked!" }, { "name": "clientID", "reason": "Invalid client ID!" } ] } ``` -------------------------------- ### Scaffold Integrated Testing Project Source: https://fast-endpoints.com/docs/scaffolding Creates a new FastEndpoints starter project that co-locates xUnit tests with their corresponding endpoints. This is useful for tightly coupled testing. ```bash dotnet new feintproj -n MyAwesomeProject ``` -------------------------------- ### JSON Error Response Example Source: https://fast-endpoints.com/docs/command-bus Example of a JSON error response when command handlers and endpoints manipulate the error state. It aggregates general errors and field-specific errors. ```json { "statusCode": 400, "message": "One or more errors occured!", "errors": { "generalErrors": [ "an error added by the endpoint!", "no jedi allowed here!" ], "firstName": [ "first name is too short!" ] } } ``` -------------------------------- ### Define Service Interface and Implementation Source: https://fast-endpoints.com/docs/dependency-injection Defines the interface and a concrete implementation for a simple 'Hello World' service. ```csharp public interface IHelloWorldService { string SayHello(); } public class HelloWorldService : IHelloWorldService { public string SayHello() => "hello world!"; } ``` -------------------------------- ### Configure Reflection Source Generator Source: https://fast-endpoints.com/docs/configuration-settings Use the Reflection Source Generator by wiring it up at startup to avoid runtime expression compilation and reflection. ```csharp app.UseFastEndpoints(c => c.Binding.ReflectionCache.AddFromMyApp()) ``` -------------------------------- ### Use Slim Builder and Enable Source Generator Type Discovery Source: https://fast-endpoints.com/docs/native-aot Configure the application builder in Program.cs to use the slim builder and enable the source generator to discover all necessary types. ```csharp var bld = WebApplication.CreateSlimBuilder(args); bld.Services.AddFastEndpoints(o => o.SourceGeneratorDiscoveredTypes = DiscoveredTypes.All) ``` -------------------------------- ### Automatic Validation Error Response Source: https://fast-endpoints.com/docs/validation Example of the JSON response sent to the client when request validation fails. ```json { "StatusCode": 400, "Message": "One or more errors occured!", "Errors": { "FullName": [ "your name is required!", "your name is too short!" ], "Age": [ "we need your age!", "you are not legal yet!" ] } } ``` -------------------------------- ### Constructor Injection for Keyed Services Source: https://fast-endpoints.com/docs/dependency-injection Demonstrates constructor injection for a service registered with a specific key. ```csharp public MyEndpoint([FromKeyedServices("KeyName")]IHelloWorldService helloScv) { ... } ``` -------------------------------- ### Describe Request Parameters with Summary Method Source: https://fast-endpoints.com/docs/swagger-support Use the Summary() method to provide descriptions for route parameters and request DTO properties. ```csharp public override void Configure() { Post("admin/login/{ClientID?}"); AllowAnonymous(); Summary(s => { s.Summary = "summary"; s.Description = "description"; s.Params["ClientID"] = "client id description"; s.RequestParam(r => r.UserName, "overriden username description"); }); } ``` -------------------------------- ### Custom Request Deserialization Source: https://fast-endpoints.com/docs/configuration-settings Provides a custom function to deserialize incoming JSON request bodies. This example uses Newtonsoft.Json for deserialization. ```csharp app.UseFastEndpoints(c => { c.Serializer.RequestDeserializer = async (req, tDto, jCtx, ct) => { using var reader = new StreamReader(req.Body); return Newtonsoft.Json.JsonConvert.DeserializeObject(await reader.ReadToEndAsync(), tDto); }; }); ``` -------------------------------- ### Configure Publisher Persistence with Known Subscribers Source: https://fast-endpoints.com/docs/remote-procedure-calls Configure the application to use custom storage providers and specify a known list of subscriber IDs. This ensures subscribers receive events from startup even if not yet connected. ```csharp app.MapHandlers(h => { h.RegisterEventHub(["worker-a", "worker-b"]); }); ``` -------------------------------- ### Implementing a Job Storage Provider with MongoDB Source: https://fast-endpoints.com/docs/job-queues This C# code demonstrates how to implement the IJobStorageProvider interface for storing and managing jobs, using a DbContext likely representing a MongoDB database. It covers storing jobs, retrieving pending jobs, marking jobs as complete, cancelling jobs by tracking ID, handling handler execution failures, and purging stale jobs. ```csharp sealed class JobStorageProvider : IJobStorageProvider { private readonly DbContext db; public bool DistributedJobProcessingEnabled => false; public JobProvider(DbContext db) { this.db = db; //inject the dbContext } public Task StoreJobAsync(JobRecord job, CancellationToken ct) { // persist the provided job record to the database return db.SaveAsync(job, ct); } public async Task> GetNextBatchAsync(PendingSearchParams p) { // return a batch of pending jobs to be processed next return await db .Find() .Match(p.Match) //use the provided boolean lambda expression to match entities .Limit(p.Limit) //either use the provided limit or choose your own .ExecuteAsync(p.CancellationToken); //pass the provided cancellation token } public Task MarkJobAsCompleteAsync(JobRecord job, CancellationToken ct) { // either replace the supplied job record in the db. // or do a partial update of just the 'IsComplete' property. // or delete the entity now if batch deleting later is not preferred. return db .Update() .MatchID(job.ID) .Modify(r => r.IsComplete, true) .ExecuteAsync(ct); } public Task CancelJobAsync(Guid trackingId, CancellationToken ct) { // do a partial update of just the 'IsComplete' property. // or delete the entity now if batch deleting later is not preferred. return db.Update() .Match(r => r.TrackingID == trackingId) .Modify(r => r.IsComplete, true) .ExecuteAsync(ct); } public Task OnHandlerExecutionFailureAsync(JobRecord job, Exception e, CancellationToken c) { // this is called whenever execution of a command's handler fails. // do nothing here if you'd like it to be automatically retried. // or update the 'ExecuteAfter' property to reschedule it to a future time. // or delete (or mark as complete) the entity if retry is unnecessary. return db .Update() .MatchID(job.ID) .Modify(r => r.ExecuteAfter, DateTime.UtcNow.AddMinutes(1)) .ExecuteAsync(c); } public Task PurgeStaleJobsAsync(StaleJobSearchParams p) { // this method is called hourly. // do whatever you like with the stale (completed/expired) jobs. return db.DeleteAsync(p.Match, p.CancellationToken); } } ``` -------------------------------- ### Configure Endpoint Caching Duration Source: https://fast-endpoints.com/docs/response-caching Specify a caching duration in seconds for a specific endpoint. This example caches the response for 60 seconds. ```csharp public class MyEndpoint : EndpointWithoutRequest { public override void Configure() { Get("/api/cached-ticks"); ResponseCache(60); //cache for 60 seconds } public override Task HandleAsync(CancellationToken ct) { return Send.OkAsync(new { Message = "this response is cached" Ticks = DateTime.UtcNow.Ticks }); } } ``` -------------------------------- ### Registering Custom JSON Converters Source: https://fast-endpoints.com/docs/model-binding Demonstrates how to register custom System.Text.Json converters during FastEndpoints startup to handle unsupported complex types. ```csharp app.UseFastEndpoints(c => { c.Serializer.Options.Converters.Add(new CustomConverter()); }); ``` -------------------------------- ### Custom App Fixture for Testing Source: https://fast-endpoints.com/docs/integration-unit-testing Defines a custom AppFixture by inheriting from AppFixture. Override methods for setup, configuration, service registration, and teardown. ```csharp public class MyApp : AppFixture { protected override ValueTask SetupAsync() { // place one-time setup code here } protected override void ConfigureApp(IWebHostBuilder a) { // do host builder config here } protected override void ConfigureServices(IServiceCollection s) { // do test service registration here } protected override ValueTask TearDownAsync() { // do cleanups here } } ``` -------------------------------- ### Enable Problem Details Error Handling Source: https://fast-endpoints.com/docs/configuration-settings Enables RFC compatible error responses by default. This is a simple startup configuration. ```csharp app.UseFastEndpoints(x => x.Errors.UseProblemDetails()); ``` -------------------------------- ### Configure Endpoint with Attributes Source: https://fast-endpoints.com/docs Use attributes like HttpPost, Authorize, and PreProcessor to configure endpoint behavior and routing directly on the endpoint class. ```csharp [HttpPost("/my-endpoint")] [Authorize(Roles = "Admin,Manager")] [PreProcessor] public class MyEndpoint : Endpoint { ... } ``` -------------------------------- ### Enable Response Caching Middleware Source: https://fast-endpoints.com/docs/response-caching Add the response caching service and middleware to your application pipeline. This setup is required before configuring individual endpoints for caching. ```csharp var bld = WebApplication.CreateBuilder(); bld.Services .AddFastEndpoints() .AddResponseCaching(); //add this var app = bld.Build(); app.UseResponseCaching() //add this before FE .UseFastEndpoints(); app.Run(); ``` -------------------------------- ### Customize Schema Generation with TypeMapper Source: https://fast-endpoints.com/docs/swagger-support Registers a TypeMapper to customize schema generation for a specific type, such as overriding the schema for Guid to be a string with 'uuid' format. ```csharp .SwaggerDocument( o => o.DocumentSettings = s => s.SchemaSettings.TypeMappers.Add( new PrimitiveTypeMapper( typeof(Guid), //the type you'd like to override the schema for schema => { schema.Type = JsonObjectType.String; schema.Format = "uuid"; } ) ) ) ``` -------------------------------- ### Create Endpoint Class Source: https://fast-endpoints.com/docs Defines a POST endpoint at /api/user/create that accepts MyRequest and returns MyResponse. Anonymous access is allowed. ```csharp public class MyEndpoint : Endpoint { public override void Configure() { Post("/api/user/create"); AllowAnonymous(); } public override async Task HandleAsync(MyRequest req, CancellationToken ct) { await Send.OkAsync(new() { FullName = req.FirstName + " " + req.LastName, IsOver18 = req.Age > 18 }); } } ``` -------------------------------- ### Configure Global Endpoint Options Source: https://fast-endpoints.com/docs/configuration-settings Apply common settings to endpoints based on their routes during application startup. Inspect the EndpointDefinition to conditionally configure options like anonymous access or host requirements. ```csharp app.UseFastEndpoints(c => { c.Endpoints.Configurator = ep => { if (ep.Routes[0].StartsWith("/public") is true) { ep.AllowAnonymous(); ep.Options(b => b.RequireHost("www.domain.com")); ep.Description(b => b.Produces(400, "application/problem+json")); } }; }); ``` -------------------------------- ### Define a State Bag Class Source: https://fast-endpoints.com/docs/pre-post-processors Create a class to hold shared state that will be passed to pre-processors, post-processors, and the endpoint. This example uses a Stopwatch to track duration. ```csharp public class MyStateBag { private readonly Stopwatch _sw = new(); public bool IsValidAge { get; set; } public string Status { get; set; } public long DurationMillis => _sw.ElapsedMilliseconds; public MyStateBag() => _sw.Start(); } ``` -------------------------------- ### Configure Event Hub in Event Broker Mode Source: https://fast-endpoints.com/docs/remote-procedure-calls Set up an event hub to act as an event broker, allowing remote publishers to send events to the hub for distribution to subscribers. ```csharp app.MapHandlers(h => { h.RegisterEventHub(HubMode.EventBroker); }); ``` -------------------------------- ### Basic Test Class with xUnit Source: https://fast-endpoints.com/docs/integration-unit-testing Inherit from TestBase and inject your AppFixture via the constructor to create a test class. xUnit will automatically provide the fixture instance. ```csharp public class MyTests(MyApp App) : TestBase { [Fact, Priority(1)] public async Task Invalid_User_Input() { var (rsp, res) = await App.Client.POSTAsync(new() { FirstName = "x", LastName = "y" }); rsp.StatusCode.ShouldBe(HttpStatusCode.BadRequest); res.Errors.Count.ShouldBe(2); res.Errors.Keys.ShouldBe(["firstName", "lastName"]); } [Fact, Priority(2)] public async Task Valid_User_Input() { var (rsp, res) = await App.Client.POSTAsync(new() { FirstName = "Mike", LastName = "Kelso" }); rsp.IsSuccessStatusCode.ShouldBeTrue(); res.Message.ShouldBe("Hello Mike Kelso..."); } } ``` -------------------------------- ### Filter Endpoint Registration by Tag Source: https://fast-endpoints.com/docs/configuration-settings Register endpoints with tags and then use a filtering function to exclude endpoints based on these tags. This example filters out endpoints tagged as 'Deprecated'. ```csharp public override void Configure() { Get("client/update"); Tags("Deprecated", "ToBeDeleted"); // has no relationship with Swagger tags } ``` ```csharp app.UseFastEndpoints(c => { c.Endpoints.Filter = ep => { if (ep.EndpointTags?.Contains("Deprecated") is true) { return false; // don't register this endpoint } return true; }; }); ``` -------------------------------- ### Configure Remote Endpoint Channel Options Source: https://fast-endpoints.com/docs/remote-procedure-calls Specify GrpcChannelOptions at startup to configure connection and retry behavior for remote endpoints. ```csharp app.MapRemote("http://localhost:6000", c => { c.ChannelOptions.MaxRetryAttempts = 5; c.ChannelOptions.HttpHandler = new() { ... }; c.ChannelOptions.ServiceConfig = new() { ... }; }); ``` -------------------------------- ### JavaScript EventSource Subscription Source: https://fast-endpoints.com/docs/server-sent-events Subscribe to a Server-Sent Events stream in the browser using the EventSource API. This example listens for a specific event type and logs the received data. ```javascript ``` -------------------------------- ### C# Server-Sent Events Endpoint Source: https://fast-endpoints.com/docs/server-sent-events Implement an endpoint that pushes real-time data using Server-Sent Events. This example sends a continuous stream of a single event type. ```csharp public class EventStream : EndpointWithoutRequest { public override void Configure() { Get("event-stream"); AllowAnonymous(); Options(x => x.RequireCors(p => p.AllowAnyOrigin())); } public override async Task HandleAsync(CancellationToken ct) { //simply provide any IAsyncEnumerable for the 2nd argument await Send.EventStreamAsync("my-event", GetDataStream(ct), ct); } private async IAsyncEnumerable GetDataStream([EnumeratorCancellation] CancellationToken ct) { while (!ct.IsCancellationRequested) { await Task.Delay(1000); yield return new { guid = Guid.NewGuid() }; } } } ``` -------------------------------- ### Configure Swagger Document with Release Version Source: https://fast-endpoints.com/docs/api-versioning Sets up a Swagger document to use the 'release version' strategy, specifying the document name and the associated release version. ```csharp bld.Services.SwaggerDocument(o => { o.DocumentSettings = d => d.DocumentName = "Release 2"; o.ReleaseVersion = 2; }) ``` -------------------------------- ### Enable XML Documentation Generation Source: https://fast-endpoints.com/docs/swagger-support Configure the project's csproj file to generate XML documentation files and suppress CS1591 warnings. ```xml true CS1591 ``` -------------------------------- ### Define Command and Handler Source: https://fast-endpoints.com/docs/job-queues Define your command contract and its corresponding handler using ICommand and ICommandHandler. This sets up the data and logic for background jobs. ```csharp sealed class MyCommand : ICommand { ... } sealed class MyCommandHandler : ICommandHandler { public Task ExecuteAsync(MyCommand command, CancellationToken ct) { ... } } ``` -------------------------------- ### Add JWT Bearer Authentication and Authorization Source: https://fast-endpoints.com/docs/security Install the FastEndpoints.Security package and register JWT Bearer authentication and authorization services. This sets up the necessary middleware for JWT-based security. ```bash dotnet add package FastEndpoints.Security ``` ```csharp using FastEndpoints; using FastEndpoints.Security; //add this var bld = WebApplication.CreateBuilder(); bld.Services .AddAuthenticationJwtBearer(s => s.SigningKey = "The secret used to sign tokens") //add this .AddAuthorization() //add this .AddFastEndpoints(); var app = bld.Build(); app.UseAuthentication() //add this .UseAuthorization() //add this .UseFastEndpoints(); app.Run(); ``` -------------------------------- ### Deprecate an Endpoint at a Specific Version Source: https://fast-endpoints.com/docs/api-versioning Mark an endpoint to be hidden from Swagger documentation starting from a specified version. This affects documentation visibility but not the endpoint's runtime availability. ```csharp Version(1, deprecateAt: 4); ``` -------------------------------- ### Registering Open Generic Middleware Components Source: https://fast-endpoints.com/docs/command-bus Registers multiple open-generic middleware components in the desired execution order. ```csharp bld.Services.AddCommandMiddleware( c => { c.Register(typeof(CommandLogger<,>), typeof(CommandValidator<,>), typeof(ResultLogger<,>)); }); ``` -------------------------------- ### Enable Serving Static Files & Swagger Doc Export Source: https://fast-endpoints.com/docs/native-aot Enable serving static files and exporting swagger docs. The order of these statements is important: Static file middleware > UseFastEndpoints > ExportSwaggerDocsAndExitAsync. The static file middleware is necessary to serve the generated swagger doc JSON files for Scalar to load. The ExportSwaggerDocsAndExitAsync() call must be placed right after UseFastEndpoints(). ```csharp app.UseStaticFiles() app.UseFastEndpoints(); await app.ExportSwaggerDocsAndExitAsync("v1", "v2"); //must match doc names above ``` -------------------------------- ### JSON Object Query Parameter (Address) Source: https://fast-endpoints.com/docs/model-binding Provides an example of passing a JSON object representing an address as a query parameter. This demonstrates binding to nested or complex DTO properties. ```url ?Address={"Street":"23 Mulholland Drive","City":"LA"} ``` -------------------------------- ### Custom Response Serialization Source: https://fast-endpoints.com/docs/configuration-settings Overrides the default response serialization process by providing a function to serialize outgoing JSON responses directly to the response stream. This example uses Newtonsoft.Json. ```csharp app.UseFastEndpoints(c => { c.Serializer.ResponseSerializer = (rsp, dto, cType, jCtx, ct) => { rsp.ContentType = cType; return rsp.WriteAsync(Newtonsoft.Json.JsonConvert.SerializeObject(dto), ct); }; }); ``` -------------------------------- ### Custom Send Method Example Source: https://fast-endpoints.com/docs/misc-conveniences Defines a custom extension method 'SendStatusCode' for IResponseSender to set a specific HTTP status code. Remember to always call sender.HttpContext.MarkResponseStart() and sender.HttpContext.Response.StartAsync(). ```csharp public static class SendExtensions { public static Task SendStatusCode(this IResponseSender sender, int statusCode) { sender.HttpContext.MarkResponseStart(); //don't forget to always do this sender.HttpContext.Response.StatusCode = statusCode; return sender.HttpContext.Response.StartAsync(); } } ``` ```csharp public override async Task HandleAsync(Request r, CancellationToken ct) { await Send.StatusCode(219); } ``` -------------------------------- ### Implement a Custom State Fixture Source: https://fast-endpoints.com/docs/integration-unit-testing Define a custom state fixture by inheriting from StateFixture. Implement SetupAsync for initialization and TearDownAsync for cleanup. This allows sharing state across test methods within a test class. ```csharp public sealed class MyState : StateFixture { public int Id { get; set; } //some state protected override async ValueTask SetupAsync() { Id = 123; //some setup logic await ValueTask.CompletedTask; } protected override async ValueTask TearDownAsync() { Id = 0; //some teardown logic await ValueTask.CompletedTask; } } public class MyTests(MyApp App, MyState State) : TestBase { [Fact] public async Task State_Check() => State.Id.ShouldBe(123); } ``` -------------------------------- ### Generate API Clients on App Run Source: https://fast-endpoints.com/docs/swagger-support Configures the application to generate API clients when run with the '--generateclients true' commandline argument. This is useful for CI/CD pipelines. ```csharp var bld = WebApplication.CreateBuilder(args); //must pass in the args bld.Services .AddFastEndpoints() .SwaggerDocument(o => { o.DocumentSettings = s => s.DocumentName = "v1"; //must match doc name below }); var app = bld.Build(); app.UseFastEndpoints(); await app.GenerateApiClientsAndExitAsync( c => { c.SwaggerDocumentName = "v1"; //must match doc name above c.Language = GenerationLanguage.CSharp; c.OutputPath = Path.Combine(app.Environment.WebRootPath, "ApiClients", "CSharp"); c.ClientNamespaceName = "MyCompanyName"; c.ClientClassName = "MyCsClient"; c.CreateZipArchive = true; //if you'd like a zip file as well }, c => { c.SwaggerDocumentName = "v1"; c.Language = GenerationLanguage.TypeScript; c.OutputPath = Path.Combine(app.Environment.WebRootPath, "ApiClients", "Typescript"); c.ClientNamespaceName = "MyCompanyName"; c.ClientClassName = "MyTsClient"; }); app.Run(); ``` -------------------------------- ### Conditional Middleware Configuration (WebApplication) Source: https://fast-endpoints.com/docs/swagger-support Use these extension methods on WebApplication to conditionally configure middleware pipelines based on the application's running mode (generation, client generation, or swagger export). ```csharp app.IsNotGenerationMode(); //returns true if running normally app.IsApiClientGenerationMode(); //returns true if running in client gen mode app.IsSwaggerJsonExportMode(); //returns true if running in swagger export mode ``` -------------------------------- ### Property Injection for Keyed Services Source: https://fast-endpoints.com/docs/dependency-injection Demonstrates property injection for a service registered with a specific key. ```csharp [KeyedService("KeyName")] public IHelloWorldService HelloService { get; set; } ``` -------------------------------- ### Custom Global Request Binder Implementation Source: https://fast-endpoints.com/docs/model-binding Provides an example of a custom global request binder that deserializes JSON content and conditionally sets a TenantId property. This binder replaces the default binder for all endpoints unless overridden. ```csharp public class MyRequestBinder : IRequestBinder where TRequest : notnull, new() { public async ValueTask BindAsync(BinderContext ctx, CancellationToken ct) { if (ctx.HttpContext.Request.HasJsonContentType()) { var req = await JsonSerializer.DeserializeAsync( ctx.HttpContext.Request.Body, ctx.SerializerOptions, ct); if (req is IHasTenantId r) r.TenantId = ctx.HttpContext.Request.Headers["x-tenant-id"]; return req!; } return new(); } } ``` -------------------------------- ### DTO with Mixed Binding Sources and Required Properties Source: https://fast-endpoints.com/docs/model-binding Defines a DTO with properties intended to be bound from different sources (route parameters and JSON body) using the 'required' keyword. This setup can lead to serializer errors if not handled correctly. ```csharp sealed class UpdateRequest { public required int Id { get; set; } //bound from route param public required string Name { get; set; } //bound from json body public required int Age { get; init; } //bound from json body } ``` -------------------------------- ### Configure JWT Token Creation Options Globally Source: https://fast-endpoints.com/docs/security Set global options for JWT token creation, such as the signing key, by configuring JwtCreationOptions in the service collection. This allows for simpler token creation calls later. ```csharp bld.Services.Configure( o => o.SigningKey = "..." ); ``` -------------------------------- ### Register Generated SerializerContext & Reflection Data Source: https://fast-endpoints.com/docs/native-aot Hook up generated serializer contexts and reflection data. The extension method name will have your assembly name at the end. If your endpoints are located in separate projects, install the FastEndpoints.Generator in each one, and chain the generated extension methods from those projects. ```csharp app.UseFastEndpoints( c => { c.Serializer.Options.AddSerializerContextsFromMyWebApp(); c.Binding.ReflectionCache.AddFromMyWebApp(); }); ``` -------------------------------- ### Create New Feature File Set with Dotnet New Source: https://fast-endpoints.com/docs/scaffolding Use the dotnet new feat command to create a new feature file set with specified parameters for namespace, method, route, and output directory. ```bash dotnet new feat -n MyProject.Comments.Create -m post -r api/comments -o Features/Comments/Create ``` -------------------------------- ### Configure Endpoint with Route Parameters Source: https://fast-endpoints.com/docs/model-binding Configure the endpoint's route template to include placeholders for parameters that will be bound to the request DTO. ```csharp public class MyEndpoint : Endpoint { public override void Configure() { Get("/api/{MyString}/{MyBool}/{MyInt}/{MyLong}/{MyDouble}/{MyDecimal}"); } } ``` -------------------------------- ### Enable Native AOT Publishing in Project File Source: https://fast-endpoints.com/docs/native-aot Add MSBuild properties to your .csproj file to enable Native AOT publishing. The InvariantGlobalization property is optional but recommended. ```xml true true ```