Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add global rate limiting sample and much more #619

Closed
wants to merge 5 commits into from

Conversation

64J0
Copy link
Member

@64J0 64J0 commented Oct 5, 2024

Description

Warning

This is just experimental. To be honest I don't like this configuration that demands an empty list. I'll ask for more opinions before making this huge change to the Giraffe codebase.

With this PR, I'm:

  • Adding a global rate limiting sample;
  • Updating the code to work only with .NET 8 (due to the ASP.NET extensions);
  • Adding the possibility to configure "ASP.NET extensions", which are middlewares like CacheOutput and RateLimiting, per route;
  • Adding a new rate limiting sample that deals with this mechanism.

TODO:

  • Filter repeated "ASP.NET extensions" to use the last value only;
  • Update docs;
  • Q: Is it possible to add OpenApi native configuration from ASP.NET?;
  • Add automated tests.

How to test

Check the instructions at the sample's README.md.

Related issues

Related to #618.

@64J0 64J0 changed the title Add rate limiting sample Add global rate limiting sample Oct 5, 2024
@64J0 64J0 self-assigned this Oct 5, 2024
@64J0 64J0 added the samples Issue related to sample projects label Oct 5, 2024
64J0 added 2 commits October 22, 2024 17:38
add ASP.NET extensions configuration to the EndpointRouting mechanism,
update samples, making a distinction between GlobalRateLimiting and RateLimiting
@64J0 64J0 force-pushed the add-rate-limit-sample branch from 7123472 to 489e937 Compare October 22, 2024 22:48
@64J0 64J0 changed the title Add global rate limiting sample Add global rate limiting sample and much more Oct 22, 2024
@64J0 64J0 added api change Change of external/internal API and/or breaking change. requires more investigation Issue requires more investigation by Giraffe devs before deciding on next steps labels Oct 22, 2024
Copy link
Contributor

@nojaf nojaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One user on #618 requesting a feature is typically not a strong enough reason to make drastic changes to the public API. I would only consider it if the demand were significantly higher.

As a workaround, you can use:

    type Endpoint =
        | SimpleEndpoint of HttpVerb * RouteTemplate * HttpHandler * ConfigureEndpoint
        | TemplateEndpoint of
            HttpVerb *
            RouteTemplate *
            RouteTemplateMappings *
            (obj -> HttpHandler) *
            ConfigureEndpoint
        | NestedEndpoint of RouteTemplate * Endpoint list * ConfigureEndpoint
        | MultiEndpoint of Endpoint list
#if NET8_0
        | NewThingWithRateLimiting of blah
#endif

Additionally, consider introducing a similar DSL function wrapped in #if NET8_0. I understand this may complicate things, but it's a better approach than altering the API on a whim.

Alternatively, you could release another major version, but be cautious not to have too many, as end-users will always have upgrade work on their side.

On a practical note, launching another major version to drop support for net6.0 after the release of net9.0 in November seems reasonable. Ultimately, I believe this change should be communicated more clearly and not be a side effect of a PR.

@@ -232,39 +270,48 @@ module Routers =
let TRACE = applyHttpVerbToEndpoints TRACE
let CONNECT = applyHttpVerbToEndpoints CONNECT

let route (path: string) (handler: HttpHandler) : Endpoint =
SimpleEndpoint(HttpVerb.NotSpecified, path, handler, id)
let route (path: string) (aspNetExtensions: AspNetExtension list) (handler: HttpHandler) : Endpoint =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is massive breaking change is it not?
Is means every existing code with route would break.

I'd go for the following:

let routeWithExtensions (path: string) (aspNetExtensions: AspNetExtension list) (handler: HttpHandler) : Endpoint = SimpleEndpoint(HttpVerb.NotSpecified, path, handler, id, aspNetExtensions)

let route (path: string) (handler: HttpHandler) : Endpoint = routeWithExtensions(path, [], handler)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it looks a better path to go

@@ -8,7 +8,7 @@
<NeutralLanguage>en-GB</NeutralLanguage>

<!-- Build settings -->
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another breaking change here.

@@ -54,16 +54,16 @@
<IncludeAssets>build</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="G-Research.FSharp.Analyzers" Version="0.10.0">
<PackageReference Include="G-Research.FSharp.Analyzers" Version="0.11.0">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating analyzers is best handled in a separate PR, to be honest. It can make the current PR noisy, and I generally find that smaller PRs focusing on one thing are easier to review.

@ebellani
Copy link

👍

@64J0
Copy link
Member Author

64J0 commented Oct 24, 2024

I'm closing this PR in favor of more succinct ones, which I'll open later, tackling specific points of the ideas presented here.

@64J0 64J0 closed this Oct 24, 2024
@64J0 64J0 deleted the add-rate-limit-sample branch October 24, 2024 21:24
let route (path: string) (handler: HttpHandler) : Endpoint =
SimpleEndpoint(HttpVerb.NotSpecified, path, handler, id)
let route (path: string) (aspNetExtensions: AspNetExtension list) (handler: HttpHandler) : Endpoint =
SimpleEndpoint(HttpVerb.NotSpecified, path, handler, id, aspNetExtensions)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something that has potential 🤔

This function that currently uses the id function has this type:

type ConfigureEndpoint = IEndpointConventionBuilder -> IEndpointConventionBuilder

I don't know much about it, but maybe we can use it instead of this custom wrapper for Asp.Net extensions https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.iendpointconventionbuilder?view=aspnetcore-9.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api change Change of external/internal API and/or breaking change. requires more investigation Issue requires more investigation by Giraffe devs before deciding on next steps samples Issue related to sample projects
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants