I'm very much in favor of this functionality, if not necessarily the proposal as written (I haven't read through it thoroughly enough to judge it one way or the other). But I have long wanted the ability to annotate types, methods, and properties, and then be able to enumerate those annotated types at runtime (to access properties, call methods, or instantiate types).
The use case foremost in my mind is server-side programming. The Java Spring Framework has a set of annotations (declared like interfaces in Java) for configuration a web server:
@Controller
@RequestMapping("/users")
public class MainController {
@RequestMapping("current", method=GET)
public String getCurrentUser(HttpServletRequest inReq, Model inModel) {
User user = …;
inModel.addAttribute("user", user);
return "userPage"; // returns the name of the .jsp file to render
}
@RequestMapping(method=POST)
public String login(HttpServletRequest inReq, Model inModel) {
String login = inModel.get("login");
String password = inModel.get("password");
let user = // fetch user record from login & password
inModel.addAttribute("user", user);
return "userPage"; // returns the name of the .jsp file to render
}
⋮
}
At run time, Java uses its introspection capabilities to find all classes that are annotated with @Controller
, instantiates one of each, and then looks for all methods with each of those annotated with @RequestMapping
, and builds up a table of routes. In this case, it would use getCurrentUser()
to handle GET requests to /users/current
, and login()
for POST requests to /users/login
.
Over on the Vapor discord, we chatted about a way to do this with macros using what I called “marker” macros. Someone else had the same idea a couple days earlier and has fairly complete working example. But it generates the route registration code at build time (not unreasonable), not at run time.
Also, I prefer the spelling @annotation
to @reflectionMetadata
.