-
-
Notifications
You must be signed in to change notification settings - Fork 1
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
File-based routing #66
Comments
A couple more things that came to my head as I was moving all my APIs to IA: AreasMy project uses areas, particularly for admin-only endpoints. Would be nice to support areas somehow.
The above should produce endpoints:
Whether it's achieved by convention like ASP does it by default, that is treating each directory in VersioningSimilarly to the above, API versioning is often handled with separate directories as well:
which should work out of the box, seeing how they are directories after all, but perhaps something more needs to be done to make it work with NSwag, Swashbuckle, and the bunch. Route Patterns...?Both of the above, as well as any potential future advanced uses could maybe be handled by a route pattern. It could use RegEx, and the route would consist of consecutive capture groups [assembly: FileSystemRouting(
NamingPolicy = NamingPolicy.LowerCase,
RoutePattern = "App\.(?:Areas\.)?(\w+).(.+)"
)] (regex101) The above would produce
Additionally — and I'm probably getting into the area of way overcomplicating what started as a simple proposal — it could support named capture groups and a template using those names: [assembly: FileSystemRouting(
NamingPolicy = NamingPolicy.LowerCase,
RoutePattern = "App\.(?:Areas\.)?(?<root>\w+)\.?(?<version>V\d)?\.(.+)",
RouteTemplate = "[root]/[version?]/[...]"
)] (regex101) which, with the following placeholder meanings
would produce the same. |
Another thought... What if it could make use of
// ApiGroup.cs
[MapGroup("api")]
public static partial class ApiGroup; // FooGroup.cs
[MapGroup("foo")]
public static partial class FooGroup
{
private static partial RouteGroupBuilder Configure(RouteGroupBuilder group) => group
.WithTags("foo")
.RequireAuthorization()
.WhateverOtherConfig();
} which would produce code akin to FooGroup.Configure(builder
.MapGroup("api")
.MapGroup("foo"))
.MapGet("/", GetFoo.Handler)
.MapPost("/", MakeFoo.Handler); or whatever Minimal APIs would require. Groups could be either resolved automagically, based on the namespaces, or if that's not feasible, an attribute like [MapGroup("api")]
public static partial class ApiGroup;
[MapGroup("foo")]
[Group(nameof(ApiGroup))]
public static partial class FooGroup;
[MapGet]
[Handler]
[Group(nameof(FooGroup))]
public static partial class WhateverHandler; |
Having to prefix all endpoints of a given type with a part of a path can be tedious and error-prone. What is not tedious or error-prone, is using the filesystem to drive routing.
Current state:
To have an endpoint at
POST: /api/public/products
we need:Can you spot the typo?
Proposed
To have an endpoint at
POST: /api/public/products
is as simple as:Considerations
Opt-in methods
It does not have to be the default behavior. It could be controlled globally with some
[assembly: FilesystemRouting]
attribute, or perhaps on the individual endpoint basis with a similar attribute, or some magic like[HttpPost("[file]")]
or[HttpPost(FilesystemRouting = true)]
Naming policies
What happens when a path contains a space? Should
PascalCase
directories be translated tolowercase
,kebab-case
, or something else?The easiest way would be to go with what is the default for Microsoft, or at least seems to be: whitespace and special characters get removed, everything gets translated into
PascalCase
.The best way would be to provide a choice, for example via an enum:
to be used with attributes discussed prior, for example
Base path
Endpoints don't always have to be placed in a directory at the root of the project. For various reasons, they can be placed elsewhere. A way should be provided to define the base directory. For example:
Source generator limitations
File location might not be available to a source generator. In such a case, should the namespace be used as a close approximation?
The text was updated successfully, but these errors were encountered: