I’m building a macro to define routes in Vapor and this works well and provides us type-safe routing among other benefits. However I would like to auto-register these routes and convert something like
@GET("api", "macros", "users")
func getUsers(req: Request) async throws -> String {
return "Users"
}
into
func getUsers(req: Request) async throws -> String {
return "Users"
}
@Sendable func _route_getUsers(req: Request) async throws -> Response {
let result: some ResponseEncodable = try await getUsers(req: req)
return try await result.encodeResponse(for: req)
}
let _ = app.on(.get, "api", "macros", "users", use: _route_getUsers)
If I write this code, it works fine. If I inline my macro definition it works fine. If I use the macro then I get the error Cannot find '_route_getUsers' in scope, so I’m guessing that the macro code can’t see the function defined in the macro?
I’ve also tried using another macro to do this in 2 steps, with the first macro generating:
@RouteRegistration(routeBuilder: app, method: .get, "api", "macros", "users")
@Sendable func _route_getUsers(req: Request) async throws -> Response {
let result: some ResponseEncodable = try await getUsers(req: req)
return try await result.encodeResponse(for: req)
}
Where @RouteRegistration generates the let _ = app.on(.get, "api", "macros", "users", use: _route_getUsers). However, this produces the same error.
So the question is - what am I doing wrong and how can I reference the function generated by the macro inside the macro code? This should work given I can reference variables generated by the macro inside the macro.
You can reproduce this by trying to build GitHub - vapor/vapor at non-controller-registration , which the relevant code defined in vapor/Sources/VaporMacrosPlugin/RouteRegistrationMacro.swift at non-controller-registration · vapor/vapor · GitHub and vapor/Sources/VaporMacrosPlugin/HTTPMethods/HTTPMethodMacroUtilities.swift at non-controller-registration · vapor/vapor · GitHub
(I’ve also tried returning the code as separate DeclSyntax items in the array returned by the macro expansion, returning it as a single code block and a few other workarounds to no avail)