kubacech
kubacech

Reputation: 117

Vertx web routing - multiple body handlers

I am working on file upload over REST in Vertx. I'm implementing this in existing project so there is already lot of routing definitions. I have problem defining body handler for my upload route. In existing routing definitions is first definition of body handler as follows:

router.route().handler(BodyHandler.create().setBodyLimit(1024*1024));

This should set this body handler for all incoming requests. And now later in the code I want to define special body handler for uploads:

router.post("/upload/path").handler(BodyHandler.create("/upload/dir").setBodyLimit(maxUploadSize));

But this does not work. BodyHandler is not "overriden". It only works when I define upload definition first, before the "common" body handler. So this works for me:

router.post("/upload/path").handler(BodyHandler.create("/upload/dir").setBodyLimit(maxUploadSize));
router.route().handler(BodyHandler.create().setBodyLimit(1024*1024));

But I would like to know if there is a way to define common handler first, and later some routes could define another handler. Thanks

Upvotes: 3

Views: 2440

Answers (2)

Paulo Lopes
Paulo Lopes

Reputation: 5801

You cannot "override" handlers. The BodyHandler task is to setup the proper handlers in the incomming request and parse the request body. These events are fired just once, so if you add several handlers only the first one to match will he able to handle the events.

You probably don't need to have several handlers has a top level one could parse the request body and populate the form data and file uploads properties in the routing context. So if you want it to behave differently, upload to different locations you can just perform a file move operation.

If you have the need for totally different configurations then you need to specify routes that do not intersect, for example:

router.post("/upload/path")
  .handler(BodyHandler.create("/upload/dir").setBodyLimit(maxUploadSize));
router.route("/something/else")
  .handler(BodyHandler.create().setBodyLimit(1024*1024));

As you can see the 2 routers are different and only 1 will be matched leaving you to have the right upload config.

Upvotes: 3

Xargos
Xargos

Reputation: 643

I don't think this is possible. I also struggled with this. From my experience vert.x has a route matching algorithm that matches the first possible registered route. This means that if you have

router.route().handler(BodyHandler.create().setBodyLimit(1024*1024));
router.post("/upload/path").handler(BodyHandler.create("/upload/dir").setBodyLimit(maxUploadSize));

then it will match withrouter.route().handler(BodyHandler.create().setBodyLimit(1024*1024)); first and will throw an error if you try to run the request through another body handler.

In the case of:

router.post("/upload/path").handler(BodyHandler.create("/upload/dir").setBodyLimit(maxUploadSize));
router.route().handler(BodyHandler.create().setBodyLimit(1024*1024));

It will match your body handler first and ignore the other one since it already matched a part of the path.

You could add an if clause to the

router.route().handler(BodyHandler.create().setBodyLimit(1024*1024));

where on "/upload/path" you just call next() instead of the body handler but I would not call this a good solution.

Upvotes: 1

Related Questions