Route Management
First route
In AventusSharp, each public method within a Router
class is automatically treated as a route. By default, the route names correspond to the method names and use the GET
HTTP method. For example, the code below defines two routes: /
(GET) since Index
is an alias for /
, and /test
(GET).
AventusSharp final URLs are always lowercase.
Be sure not to define any constructors in your routers.
using AventusSharp.Routes;
namespace Demo.Routes{ public class MainRouter : Router { // Route: url / (GET) public string Index() { return "It's working"; }
// Route: url /test (GET) public string Test() { return "It's a test"; } }}
Return Types
In AventusSharp, each route returns a response handled via an IResponse
interface. There are several default response types based on the return type of your route:
- If the route returns an
IResponse
directly, it is processed as-is. - If the route returns
void
, the response will be empty, with a status code of 204 (No Content). - If the route returns a
byte[]
array, aByteResponse
will be used. - If the route returns a text value, a
TextResponse
is applied. - For all other types, a
JsonResponse
is used by default.
using AventusSharp.Routes;using AventusSharp.Routes.Attributes;using AventusSharp.Routes.Response;using Demo.Data;
namespace Demo.Routes{ public class MainRouter : Router { // Route: url / (GET), returns a TextResponse public string Index() { return "It's working"; }
// Route: url /test (GET), explicitly returns a TextResponse public TextResponse Test() { return new TextResponse("It's a test"); }
// Route: url /test2 (GET), returns a JsonResponse by default public User Test2() { return new User(); } }}
List of predefined IResponse:
- DummyResponse: Returns a fixed response with the text “I’m dummy.”
- ByteResponse: Sends a byte array as the response body, with the byte array passed into the constructor.
- JsonResponse: Serializes an object to JSON using the configuration’s JSON settings.
- TextResponse: Sends a plain text response with the specified text.
- View: Renders an HTML view from the
ViewDir
directory specified in the configuration. - ViewDynamic: Renders a dynamic view using the Scriban templating engine. Requires the
Scriban
NuGet package.
Static Views
To return a static HTML view, use the View
response type. The HTML file should be placed in the configured ViewDir
directory (by default Views
).
using AventusSharp.Routes;using AventusSharp.Routes.Response;
namespace Demo.Routes{ public class MainRouter : Router { public View Index() { return new View("index"); } }}
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <p>Hello world</p></body></html>
Dynamic Views
To return a dynamic HTML view, use the ViewDynamic
response type, which leverages Scriban templating for dynamic content rendering. Install Scriban with:
dotnet add package Scriban
Then you can create your route :
using AventusSharp.Routes;using AventusSharp.Routes.Response;
namespace Demo.Routes{ public class MainRouter : Router { public ViewDynamic Index() { return new ViewDynamic("index", new { name = "John", }); } }}
This file should also be placed in the configured ViewDir
directory. It uses Scriban syntax for dynamic content, like {{name}}
, which will be replaced at runtime.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <p>Hello {{name}}</p></body></html>
You can also implement custom response types if needed.
With this setup, you have full flexibility in defining and managing your routes in AventusSharp.
Changing HTTP Methods
To define routes with HTTP methods other than GET
, use attributes like [Get]
, [Post]
, [Put]
, [Delete]
, and [Options]
. This allows you to customize each route’s HTTP method as needed.
using AventusSharp.Routes;using AventusSharp.Routes.Attributes;
namespace Demo.Routes{ public class MainRouter : Router { [Get] public string Index() { return "It's working"; }
// Route: url /test (POST) [Post] public string Test() { return "It's a test"; } }}
Custom URL Definitions
Prefixing Routes
You can add a prefix to all routes within a router using the [Prefix(string)]
attribute. This helps in grouping related routes under a common path.
using AventusSharp.Routes;using AventusSharp.Routes.Attributes;
namespace Demo.Routes{ [Prefix("Main")] public class MainRouter : Router { // Route: url => /main/ (GET) public string Index() { return "It's working"; }
// Route: url => /main/test (GET) public string Test() { return "It's a test"; } }}
Customizing Individual Route Paths
To rename individual routes, use the [Path(string)]
attribute. This allows you to define a unique path for each route.
using AventusSharp.Routes;using AventusSharp.Routes.Attributes;using Path = AventusSharp.Routes.Attributes.Path;
namespace Demo.Routes{ [Prefix("Main")] public class MainRouter : Router { // Route: url => /main/ (GET) public string Index() { return "It's working"; }
// Route: url => /main/demo (GET) [Path("/Demo")] public string Test() { return "It's a test"; } }}
URL Parameters
You can add parameters to routes by enclosing them in {}
within the path. The parameters should be defined as function arguments, and AventusSharp will automatically infer their types.
using AventusSharp.Routes;using AventusSharp.Routes.Attributes;using Path = AventusSharp.Routes.Attributes.Path;
namespace Demo.Routes{ [Prefix("Main")] public class MainRouter : Router { // Route: url => /main/ (GET) public string Index() { return "It's working"; }
// Route: url => /main/demo/{id} (GET), where {id} is inferred as an integer [Path("/Demo/{id}")] public string Test(int id) { return "It's a test for " + id; } }}
Calling Functions
You can also call functions within routes. This approach is useful when creating abstract classes for generic routers. Function calls in routes are executed at route initialization, so only predefined elements should be included. This functionality is demonstrated in the StorableRouter
class, which will be discussed later.
using AventusSharp.Routes;using Path = AventusSharp.Routes.Attributes.Path;
namespace Demo.Routes{ public class MainRouter : Router { // Route: url => / (GET) public string Index() { return "It's working"; }
// Route: url => /mainrouter/{id} (GET), where router name is generated by GetRouterName() [Path("/[GetRouterName]/{id}")] public string Test(int id) { return "It's a test for " + id; }
protected string GetRouterName() { return GetType().Name; } }}
With these tools, you can efficiently manage HTTP methods, customize URLs, handle parameters, and add dynamic functionality within your routes.
Service Injection
AventusSharp supports injecting services that can be directly used within routes. In the example below, we’ll create a simple service to provide the current date and time.
public interface IDateTime{ DateTime Now { get; }}
public class SystemDateTime : IDateTime{ public DateTime Now => DateTime.Now;}
To register a service for injection, use the static Inject
function during application initialization.
private static void InitHttp(VoidWithError initResult, WebApplication app){ RouterMiddleware.Configure((config) => {}); initResult.Run(RouterMiddleware.Register); app.Use(RouterMiddleware.OnRequest);
// Inject IDateTime service implementation RouterMiddleware.Inject<IDateTime, SystemDateTime>();}
Once injected, you can use IDateTime
in any route by including it as a parameter.
using AventusSharp.Routes;using Demo.Logic;using Path = AventusSharp.Routes.Attributes.Path;
namespace Demo.Routes{ public class MainRouter : Router { public string Time(IDateTime dateTime) { return "It's " + dateTime.Now; } }}
Request Body
Any additional parameters in a route method signature will be treated as part of the request body. To enable this functionality, install the HttpMultipartParser
NuGet package:
dotnet add package HttpMultipartParser
Then you can create route with a body
using AventusSharp.Routes;using AventusSharp.Routes.Attributes;
namespace Demo.Routes{ public class MainRouter : Router { [Post] public string Hello(string name) { return "Hello " + name; } }}
Now, you can send a request with a JSON or form body containing a name
field, and it will be automatically injected into the Hello
method.
Voici une version reformulée en anglais et formatée en Markdown pour votre documentation :
Excluding a Method from Routing
If you have a public method in your router that you do not want to expose as a route, you can use the [NoRoute]
attribute. This prevents the method from being registered as an http route.
using AventusSharp.Routes;using AventusSharp.Tools.Attributes;
namespace Demo.Routes{ public class MainRouter : WsRouter { public string Index() { return "It's working"; }
// The route /test won't exist [NoRoute] public string Test() { return "It's a test"; } }}
In this example, the /test
route won’t be created, even though the Test
method is public.
Preconfigured HTTP Routes
AventusSharp provides a preconfigured HTTP router called StorableRouter<T>
. This generic router simplifies the creation of HTTP routes for managing storable objects. The type parameter T
represents the object type you want to handle, and the name of T
is used in place of [StorableName]
in the route paths.
The following routes are automatically created:
Function | Path | HTTP Method |
---|---|---|
GetAll | /[StorableName] | GET |
Create | /[StorableName] | POST |
CreateMany | /[StorableName]s | POST |
GetById | /[StorableName]/{id} | GET |
GetByIds | /[StorableName]/GetByIds | GET |
Update | /[StorableName]/{id} | PUT |
UpdateMany | /[StorableName]s | PUT |
Delete | /[StorableName]/{id} | DELETE |
DeleteMany | /[StorableName]s | DELETE |
Key Benefits
- Ease of Use: No need to manually define standard CRUD routes.
- Standardized API: Ensures consistent HTTP routing for all your storable objects.
- Rapid Development: Focus on the logic and let the router handle the routing structure.
Example Usage
To create a router for a specific storable object, simply inherit from StorableRouter<T>
and specify your object type as the generic parameter. All the routes described above will be automatically available.
using AventusSharp.Routes;using Demo.Data;
namespace Demo.Routes{ public class UserRouter : StorableRouter<User> {
}}
This feature makes setting up HTTP routes for your objects fast and straightforward, saving time and ensuring consistency across your application.