Skip to content

chore(deps): update dependency fastendpoints to v8#20

Merged
phmatray merged 1 commit intomainfrom
renovate/major-fastendpoints-monorepo
Feb 27, 2026
Merged

chore(deps): update dependency fastendpoints to v8#20
phmatray merged 1 commit intomainfrom
renovate/major-fastendpoints-monorepo

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Feb 27, 2026

This PR contains the following updates:

Package Change Age Confidence
FastEndpoints (source) 5.35.08.0.1 age confidence

Release Notes

FastEndpoints/FastEndpoints (FastEndpoints)

v8.0.1: Release


⚠️ Sponsorship Level Critically Low ⚠️

Due to low financial backing by the community, FastEndpoints will soon be going into "Bugfix Only" mode until the situation improves. Please join the discussion here and help out if you can.


New 🎉
Support for Native AOT compilation

FastEndpoints is now Native AOT compatible. Please see the documentation here on how to configure it.

If you'd like to jump in head first, a fresh AOT primed starter project can be scaffolded like so:

dotnet new install FastEndpoints.TemplatePack
dotnet new feaot -n MyProject

If you've not worked with AOT compilation in .NET before, it's highly recommended to read the docs linked above.

Auto generate STJ JsonSerializationContexts

You no longer need to ever see a JsonSerializerContext thanks to the new serializer context generator in FastEndpoints. (Unless you want to that is 😉). See the documentation here on how to enable it for non-AOT projects.

Distributed job processing support

The job queueing functionality now has support for distributed workers that connect to the same underlying database. See the documentation here.

Qualify endpoints in global configurator according to endpoint level metadata

You can now register any object as metadata at the endpoint level like so:

sealed class SomeObject
{
    public int Id { get; set; }
    public bool Yes { get; set; }
}

sealed class MetaDataRegistrationEndpoint : EndpointWithoutRequest
{
    public override void Configure()
    {
        Get("/test-cases/endpoint-metadata-reg-test");
        Metadata(
            new SomeObject { Id = 1, Yes = true },
            new SomeObject { Id = 2, Yes = false });
    }
}

and configure endpoints conditionally at startup according to the endpoint level metadata that was added by the endpoint configure method:

app.UseFastEndpoints(
       c => c.Endpoints.Configurator =
                ep =>
                {
                    if (ep.EndpointMetadata?.OfType<SomeObject>().Any(s => s.Yes) is true)
                        ep.AllowAnonymous();
                })
Response sending method 'NotModifiedAsync'

A new response sending method has been added for sending a 304 status code response.

public override async Task HandleAsync(CancellationToken c)
{
    await Send.NotModifiedAsync();
}
Fixes 🪲
Index out of range exception in routeless test helpers

The routeless integration test helpers such as .GETAsync<>() would throw an exception when testing an endpoint configured with the root URL /, which has now been fixed.

Query/Route param culture mismatch with routeless test helpers and backend

The routeless test helpers such as .GETAsync<>() would construct route/query params (of certain primitives such as DateTime) using the culture of the machine where the tests are being run, while the application is set up to use a different culture, the tests would fail. This has been solved by constructing route/query params for primitive/IFormattable types using ISO compliant invariant culture format when constructing the requests.

Routeless testing helpers contention issue

The test helpers were using a regular dictionary to cache test URLs internally which could sometimes cause trouble under high load. This has been solved by switching to a concurrent dictionary.

Source generators having trouble with special characters in project names

The source generators were generating incorrect namespaces if the project name has dashes such as My-Project.csproj which would result in generating namespaces with dashes, which is invalid for C#.

Test collection ordering regression

Due to an internal behavior change in XUnit v3, test collection ordering was being overriden by XUnit. This has been rectified by taking matters in to our own hands and bypassing XUnit's collection runner.

Improvements 🚀
Job Queues storage processing

Several optimizations have been done to the job queues storage logic to reduce the number of queries in certain scenarios. Please see the breaking changes section below as one of the methods of IJobStorageProvider needs a minor change.

Easy access to error response content with testing helpers

You can now easily inspect why a request failed when you expected it to succeed. There's now a new string property ErrorContent on the TestResult record that routeless testing helpers return.

[Fact]
public async Task Get_Request_Responds_With_200_Ok()
{
    var (rsp, res, errorContent) = await app.Client.GETAsync<MyEndpoint, MyRequest, string>(new() { ... });

    if (rsp.IsSuccessStatusCode)
        Assert.True(...);
    else
        Assert.Fail(errorContent); //errorContent contains the error response body as a string
}
Request DTO serialization behavior of testing helpers

Testing helpers such as .POSTAsync<>() will only serialize the request DTO in to the request body if there's at least one property on the DTO that will be bound from the JSON body. In instances where nothing should be bound from the JSON body, the request body content will be empty.

Mitigate incorrect service scoping due to user error in Command Bus

If a user for whatever reason registerd command handlers as scoped services in DI themselves (when they're not supposed to), it could lead to unexpected behavior. This is no longer an issue.

Minor Breaking Changes ⚠️
New 'IJobStorageProvider.DistributedJobProcessingEnabled' property

Due to adding support for distributed job processing, all storage provider implementations must now implement the following boolean property. Simply set it to false when not using distributed job processing like so:

sealed class JobStorageProvider : IJobStorageProvider<JobRecord>
{
    public bool DistributedJobProcessingEnabled => false;
}
New 'IJobStorageRecord.DequeueAfter' property

Even though you only need to implement this property when using distributed job processing, it's recommended to either let all the jobs in your database run to completion before upgrading to v8.0 and/or run a migration to set the value of DequeueAfter to DateTime.MinValue for all jobs already in the database to ensure that they get picked up properly for processing. (Even when not using distributed processing.)

'IJobStorageProvider.GetNextBatchAsync()' return type change

As a result of optimizations done to the storage processing logic in job queues, your job storage provider implementation requires a minor change from:

public Task<IEnumerable<...>> GetNextBatchAsync(...)

to:

public Task<ICollection<...>> GetNextBatchAsync(...)

You are now required to return a materialized collection instead of an IEnumerable<T>.

v7.1.1: Release

.NET 10 Support

We've had .NET 10 preview support for a while and this is just a patch release to update the SDK references to .NET 10 final.

v7.0.1: Release


❇️ Help Keep FastEndpoints Free & Open-Source ❇️

Due to the current unfortunate state of FOSS, please consider becoming a sponsor and help us beat the odds to keep the project alive and free for everyone.


New 🎉
Relocate response sending methods ⚠️

Response sending methods such as SendOkAsync() have been ripped out of the endpoint base class for a better intellisense experience and extensibility.

Going forward, the response sending methods are accessed via the Send property of the endpoint as follows:

public override async Task HandleAsync(CancellationToken c)
{
    await Send.OkAsync("hello world!");
}

In order to add your own custom response sending methods, simply target the IResponseSender interface and write extension methods like so:

static class SendExtensions
{
    public static Task HelloResponse(this IResponseSender sender)
        => sender.HttpContext.Response.SendOkAsync("hello!");
}

This is obviously is a wide-reaching breaking change which can be easily remedied with a quick regex based find & replace. Please see the breaking changes section below for step-by-step instructions on how to migrate. Takes less than a minute.

Send multiple Server-Sent-Event models in a single stream

It is now possible to send different types of data in a single SSE stream with the use of a wrapper type called StreamItem like so:

public override async Task HandleAsync(CancellationToken ct)
{
    await Send.EventStreamAsync(GetMultiDataStream(ct), ct);

    async IAsyncEnumerable<StreamItem> GetMultiDataStream([EnumeratorCancellation] CancellationToken ct)
    {
        long id = 0;

        while (!ct.IsCancellationRequested)
        {
            await Task.Delay(1000, ct);

            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
        }
    }
}

By default, the StreamItem will be serialized as a JSON object, but you can change this by inheriting from it and overriding the GetDataString method to return a different format such as XML or plain text.

Customize param names for strongly typed route params

It is now possible to customize the route param names when using the strongly typed route params feature by simply decorating the target DTO property with a [BindFrom("customName"))] attribute. If a BindFrom attribute annotation is not present on the property, the actual name of the property itself will end up being the route param name.

Support for malformed JSON array string binding

When submitting requests via SwaggerUI where a complex object collection is to be bound to a collection property of a DTO, SwaggerUI sends in a malformed string of JSON objects without properly enclosing them in the JSON array notation [...] such as the following:

{"something":"one"},{"something":"two"}

whereas it should be a proper JSON array such as this:

[{"something":"one"},{"something":"two"}]

Since we have no control over how SwaggerUI behaves, support has been added to the default request binder to support parsing and binding the malformed comma separateed JSON objects that SwaggerUI sends at the expense of a minor performance hit.

Auto infer query parameters for routeless integration tests

If you annotate request DTO properties with [RouteParam] attribute, the helper extensions such as .GETAsync() will now automatically populate
the request query string with values from the supplied DTO instance when sending integration test requests.

sealed class MyRequest
{
    [RouteParam]
    public string FirstName { get; set; }

    public string LastName { get; set; }
}

[Fact]
public async Task Query_Param_Test()
{
    var request = new MyRequest
    {
        FirstName = "John", //will turn into a query parameter
        LastName = "Gallow" //will be in json body content
    };
    var result = await App.Client.GETAsync<MyEndpoint, MyRequest, string>(request);
}
Fixes 🪲
Header example value not picked up from swagger example request

If a request DTO specifies a custom header name that is different from the property name such as the following:

sealed class GetItemRequest
{
    [FromHeader("x-correlation-id")]
    public Guid CorrelationId { get; init; }
}

and a summary example request is provided such as the following:

Summary(s => s.ExampleRequest = new GetItemRequest()
{
    CorrelationId = "54321"
});

the example value from the summary example property was not being picked up due to an oversight.

Xml comments not picked up by swagger for request schema

There was a regression in the code path that was picking up Summary xml comments from DTO properties in certain scenarios, which has now been fixed.

Incorrect swagger example generation when '[FromBody] or [FromForm]' was used

If a request DTO was defined like this:

sealed class MyRequest
{
    [FromBody]
    public Something Body { get; set; }
}

and an example request is provided via the Summary like this:

Summary(x=>x.ExampleRequest = new MyRequest()
{
    Body = new Something()
    {
        ...
    }
});

swagger generated the incorrect request example value which included the property name, which it shouldn't have.

Default exception handler setting incorrect mime type

Due to an oversight, the default exception handler was not correctly setting the intended content-type value of application/problem+json. Instead, it was being overwritten with application/json due to not using the correct overload of WriteAsJsonAsync() method internally.

Minor Breaking Changes ⚠️
API change of endpoint response sending methods

The response sending methods are no longer located on the endpoint class itself and are now accessed via the Send property of the endpoint.
This is a breaking change which you can easily fix by doing a quick find+replace using a text editor such as VSCode. Please follow the following steps in order to update your files:

  1. Open the top level folder of where your endpoint classes exist in the project in a text editor like VSCode.
  2. Click Edit > Replace In Files and enable Regex Matching
  3. Use (?<!\.)\bSend(?=[A-Z][A-Za-z]*Async\b) as the regex to find matches to target for editing.
  4. Enter Send. in the replacement field and hit Replace All
  5. Then use (?<!\.)\bSendAsync\b as the regex.
  6. Enter Send.OkAsync as the replacement and hit Replace All again.
  7. Build the project and profit!

Note: In case some Send.OkAsync() calls won't compile, it's most likely you were using the SendAsync() overload that allowed to set a custom status code. Simply use the Send.ResponseAsync() method instead of Send.OkAsync() for those calls as OkAsync() doesn't allow custom status codes.

Here's a complete walkthrough of the above process.

Small change in the Server-Sent-Event response stream

Previously the Server-Sent-Event response was written as:

id:12345
event: my-event
data: hello world!

Notice the inconsistency in the spacing between the id, event and data fields. This has now been fixed to be consistent with the following format:

id: 12345
event: my-event
data: hello world!


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot force-pushed the renovate/major-fastendpoints-monorepo branch from f24454c to e9f9f1e Compare February 27, 2026 17:52
@phmatray phmatray merged commit 59fbdb9 into main Feb 27, 2026
1 of 2 checks passed
@phmatray phmatray deleted the renovate/major-fastendpoints-monorepo branch February 27, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant