Closed connor-ricks closed 6 days ago
I managed to get this to compile this morning... Caching is still a potential issue. I'm wondering if this is a worthwhile addition to the library or if I should simply just use this in my own project?
protocol Controller: RouterMiddleware {
associatedtype Body: RouterMiddleware
var body: Body { get }
}
extension Controller where Body.Input == Input, Body.Context == Context, Body.Output == Output {
func handle(_ input: Input, context: Context, next: (Input, Context) async throws -> Output) async throws -> Output {
try await body.handle(input, context: context, next: next)
}
}
struct UserController: Controller {
typealias Context = BasicRouterRequestContext
var body: some RouterMiddleware<Context> {
RouteGroup("user") {
Get { _,_ in
"User"
}
}
}
}
func foo() {
let router = RouterBuilder {
UserController()
}
let app = Application(responder: router)
}
It is a worthwhile addition. I think we'd want to integrate it into the result builder first though so the result builder is only evaluated at build time and not every time we call handle().
I think you'd just have to add implementations of buildExpression
, buildBlock
etc to MiddlewareFixedTypeBuilder which take a Controller parameter and dereference the controller body parameter in those functions.
Also you'd need to remove the MiddlewareProtocol conformance from Controller along with its handle function.
It'd probably be nice to implement somethings similar for the trie router as well so getting the naming right might be difficult.
Thanks for the input. I might try and play around with this a little bit this weekend. Go enjoy your vacation!
Created a small PR for this. It doesn't include support for the "trie" router, but it's a start. The fact that the Controller
has a body itself that is a builder makes me think that it belongs properly in the HummingbirdRouter
instead of the main target, but you'll definitely have more context than me. Feel free to make changes! 😄
Actively under development in #577
Copying this issue over from the example repo to move it to the more appropriate location and closing the example issue.
Hello,
I was experimenting with Hummingbird today and saw the HummingbirdRouter target was added for result builder style syntax.
While I managed to use the result builder syntax to get some routes created, I was wondering if at this point in time, it was possible to make the content feel more composable.
Most of the examples build route collections using a property called endpoints but then when they add them, they explicitly call .endpoints.
I was hoping to achieve a syntax more like this...
Just some rough syntax, but hopefully you get the idea.
Is this possible at the moment? Perusing the implementation, it seems maybe not quite, but perhaps it is pretty close.
I achieved a similar syntax with Vapor. You can take a peek here.