Java reflection and Vertx handlers

296 views
Skip to first unread message

javadevmtl

unread,
Sep 29, 2016, 1:22:13 PM9/29/16
to vert.x
Hi I'm working on a factory utility class for building REST services with Vertx but without needing to learn yet another framework...


I'm using reflection so just wondering if it's ok and if it screws up with the vertx context in any way...


public class MyAbstractVerticle extends AbstractVerticle {
public void initServer() throws IllegalAccessException, LambdaConversionException, Throwable {
Router router = Router.router(vertx);

Method[] methods = this.getClass().getMethods();
for(Method m : methods) {
Annotation[] annotations = m.getAnnotations();

if(annotations.length == 1) {
System.out.println(annotations[0].toString());
MethodHandles.Lookup lookup = MethodHandles.lookup();
Handler<RoutingContext> handler = (Handler<RoutingContext>)
 LambdaMetafactory.metafactory(lookup, "handle",
   MethodType.methodType(Handler.class, getClass()),
   MethodType.methodType(void.class, Object.class), lookup.unreflect(m),
   MethodType.methodType(void.class, RoutingContext.class))
 .getTarget().invoke(this);
if(annotations[0] instanceof GET) {
GET get = (GET) annotations[0];
router.get(get.route()).handler(handler);
} else if(annotations[0] instanceof POST) {
POST post = (POST) annotations[0];
router.post(post.route()).handler(handler);
}
}
vertx.createHttpServer().requestHandler(router::accept).listen(8181);
}
}


And then you can have regular verticle as such...

public class MyVerticle extends MyAbstractVerticle {
@Override
public void start(){
System.out.println("Starting...");
try {
super.initServer();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@GET(route="/myHandler")
public void myHandler(RoutingContext rc) {
rc.response().end("Hello Reflection!");
}
@POST(route="/myOtherHandler")
public void myOtherHandler(RoutingContext rc) {
rc.response().end("Hello Other Reflection!");
}

}

I think it's a nice non intrusive way without having to learn another framework and still have access directly to vertx. P.S: This is very rough test implementation.



ad...@cs.miami.edu

unread,
Sep 29, 2016, 2:02:54 PM9/29/16
to vert.x
Hi,

That is an interesting concept.  And if it works, a neat way to get rest apis up quick and fast (somewhat like resetlet).

My concern is that, while it may be possible to make something that will allow people to avoid "learning" another framework, this seems particularly dangerous with vertx.  Given, the event loop style of vertx, it seems hard to make something with good performance with out knowing the basics of how vertx works.  And it seems likely that a user will easily start blocking the event-loop without realizing it.

-Adam

Paulo Lopes

unread,
Sep 29, 2016, 2:09:42 PM9/29/16
to vert.x
Hi if you want other code to look into see:

https://github.com/pmlopes/vertx-web-annotations

it provides a simplified annotation based REST API builder which is a strip down version of yoke old swagger annotation support.

javadevmtl

unread,
Sep 29, 2016, 3:00:27 PM9/29/16
to vert.x
Cool I'll check it out. So far I like this because you don't need a new API just one factory method and to extend "MyAbstractVerticle" Nothing to change in the way your program.

@Controller(route="/api")

public class MyVerticle extends MyAbstractVerticle {
@Override
public void start(Future<Void> startFuture){
super.buildEndpoint(h-> {
if(h.succeeded()) {
startFuture.complete();
}
else {
startFuture.fail(h.cause());
}
});
}

@GET(route="/myHandler")
protected void myHandler(RoutingContext rc) {

javadevmtl

unread,
Sep 29, 2016, 3:12:16 PM9/29/16
to vert.x
Your way is pretty simple also :)
Message has been deleted

javadevmtl

unread,
Sep 29, 2016, 3:17:18 PM9/29/16
to vert.x
My implementation is just another AbstractVerticle. In fact "MyAbstractVerticle" (until I find a name for it) extends AbstractVerticle. It's not even a thin layer on top of vertx, it's pure vertx. It just takes care of some of the boilerplate code. See my post to Paulo.

All you do is call buildEndpoint() and it will create HttpServer and wire the routes for you.
Reply all
Reply to author
Forward
0 new messages