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:
// location: Api/Public/Products/CreateProduct.cs
[Handler]
[HttpPost("api/public/porducts")]
public static partial CreateProduct
{
// ...
}
Can you spot the typo?
Proposed
To have an endpoint at POST: /api/public/products is as simple as:
// location: Api/Public/Products/CreateProduct.cs
[Handler]
[HttpPost]
public static partial CreateProduct
{
// ...
}
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 to lowercase, 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:
public enum NamingPolicy
{
PascalCase,
CamelCase,
LowerCase,
KebabCase,
SnakeCase
}
to be used with attributes discussed prior, for example
[assembly: FileSystemRouting(
NamingPolicy = NamingPolicy.LowerCase
)]
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:
// location: Api/Handlers/Product/Create.cs
[assembly: FileSystemRouting(
RootDirectory = "Api/Handlers"
)]
[Handler]
[MapPost] // maps it to POST: /product
public static partial class CreateProduct
{
// ...
}
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?
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/productswe need:Can you spot the typo?
Proposed
To have an endpoint at
POST: /api/public/productsis 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
PascalCasedirectories 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?