Vert.x RESTful 垂直
Vert.x RESTful Verticle
我对 Vert.x 非常陌生,就像刚认识几天一样。我来自 JAX-RS、RESTeasy 世界。可能我说的很不对,还请指正
所以,我想使用 vertx-web 和 Spring 编写一个 REST API。我将 Verticles 视为 REST 资源。
我看了一下 vertx-web blog and spring-example,但是示例非常简单,而且大部分只包含一个资源和 Verticle。
我的问题是:如何让 Verticle 暴露自己的 REST 接口(子路由器),以及如何将其子路由器注册到应用程序的主路由器中?
我试过类似的方法,但是当我请求 /products/all 时得到 404 :(
public class ProductsVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> startFuture) throws Exception {
super.start(startFuture);
}
public static Router getRouter() {
Router router = Router.router(Vertx.vertx());
router.get("/all").consumes("application/json").produces("application/json")
.handler(routingContext -> {
routingContext.response()
.putHeader("content-type", "text/html")
.end("<h1>Products</h1>");
});
return router;
}
}
public class ServerVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
super.start();
Router mainRouter = Router.router(vertx);
ProductsVerticle productsVerticle = new ProductsVerticle();
vertx.deployVerticle(productsVerticle, handler -> {
if (handler.succeeded()) {
LOG.info("Products Verticle deployed successfully");
mainRouter.mountSubRouter("/products", productsVerticle.getRouter());
}
});
mainRouter.get("/static").handler(routingContext -> {
routingContext.response()
.putHeader("content-type", "text/html")
.end("<h1>Hello from my first Vert.x 3 application</h1>");
});
HttpServer server = vertx.createHttpServer();
server.requestHandler(mainRouter::accept);
server.listen(8090);
}
}
您的需求完全可以理解。但是我们也许应该很快考虑一下 spring 的作用:
- 当应用程序服务器启动时,会执行启动挂钩,它会在整个 class 路径中搜索每个用 Jax-rs 标注的 class 并初始化它们,或者只是将它们注册到 "router" 上。
所以如果你想要那个,你可以拥有那个,但你必须自己做。对不起:D。
例如:
class Server extends AbstractVerticle {
@Override
public void start() throws Exception {
List<AbstractVerticle> verticles = searchForVerticlesWithMyAnnotation();
verticles.forEach((V) = > router.add(V));
}
}
@MyOwnJax(path = "/blaa")
public class TestService {
}
@interface MyOwnJax {
String path();
}
方法"searchForVerticlesWIthMyAnnotation" 是这里的棘手问题。它不应该太慢。但是如果你使用 Spring 无论如何你可以使用类似的东西:
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
或看这里:Whosebug: Search for Annotations @runtime
BUT 这是一个很大的但是在这里。 ;)
也许你有更好的主意 Spring 让你的 REST api ?
Spring 在我看来真的是 "klobby" 而 Vertx.x 真的很流畅。 (我对我的不切实际的意见感到抱歉。)
我在我的应用程序中使用了一种 DI 方法。这意味着:
router.route(HttpMethod.GET,
"/user/login").handler(injector.getInstance(ILoginUser.class));
使用普通的guice框架作为注入器。虽然这只是一个接口,但您可以在必须更改启动服务器的 Verticle 中的某些内容之前进行非常大的更改。 (实际上主要是如果你必须添加或删除路径)
总结:
如果您想使用 Spring 方法,您必须使用反射或使用反射的库。
缺点:Startup-performance,有时有点太神奇了,真的很难找到 errors/debug。
好处:非常容易测试,扩展功能真的非常容易
自己在路径上注册Verticles。
缺点:您必须在 "server"-verticle 上添加/删除路径。
好处:Startup-performance,没有魔法,完全控制发生的事情和时间。
这只是一个简短的总结,很多要点都没有提到。但我希望这能回答你的问题。如果您有一些后续问题,请写信!
杰尔泽,
西米
我最近为 vert.x.
编写了一个简单的 JAX-RS 注释库
它的方法类似于 RestEasy。
我对 Vert.x 非常陌生,就像刚认识几天一样。我来自 JAX-RS、RESTeasy 世界。可能我说的很不对,还请指正
所以,我想使用 vertx-web 和 Spring 编写一个 REST API。我将 Verticles 视为 REST 资源。 我看了一下 vertx-web blog and spring-example,但是示例非常简单,而且大部分只包含一个资源和 Verticle。
我的问题是:如何让 Verticle 暴露自己的 REST 接口(子路由器),以及如何将其子路由器注册到应用程序的主路由器中?
我试过类似的方法,但是当我请求 /products/all 时得到 404 :(
public class ProductsVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> startFuture) throws Exception {
super.start(startFuture);
}
public static Router getRouter() {
Router router = Router.router(Vertx.vertx());
router.get("/all").consumes("application/json").produces("application/json")
.handler(routingContext -> {
routingContext.response()
.putHeader("content-type", "text/html")
.end("<h1>Products</h1>");
});
return router;
}
}
public class ServerVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
super.start();
Router mainRouter = Router.router(vertx);
ProductsVerticle productsVerticle = new ProductsVerticle();
vertx.deployVerticle(productsVerticle, handler -> {
if (handler.succeeded()) {
LOG.info("Products Verticle deployed successfully");
mainRouter.mountSubRouter("/products", productsVerticle.getRouter());
}
});
mainRouter.get("/static").handler(routingContext -> {
routingContext.response()
.putHeader("content-type", "text/html")
.end("<h1>Hello from my first Vert.x 3 application</h1>");
});
HttpServer server = vertx.createHttpServer();
server.requestHandler(mainRouter::accept);
server.listen(8090);
}
}
您的需求完全可以理解。但是我们也许应该很快考虑一下 spring 的作用: - 当应用程序服务器启动时,会执行启动挂钩,它会在整个 class 路径中搜索每个用 Jax-rs 标注的 class 并初始化它们,或者只是将它们注册到 "router" 上。
所以如果你想要那个,你可以拥有那个,但你必须自己做。对不起:D。
例如:
class Server extends AbstractVerticle {
@Override
public void start() throws Exception {
List<AbstractVerticle> verticles = searchForVerticlesWithMyAnnotation();
verticles.forEach((V) = > router.add(V));
}
}
@MyOwnJax(path = "/blaa")
public class TestService {
}
@interface MyOwnJax {
String path();
}
方法"searchForVerticlesWIthMyAnnotation" 是这里的棘手问题。它不应该太慢。但是如果你使用 Spring 无论如何你可以使用类似的东西: org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
或看这里:Whosebug: Search for Annotations @runtime
BUT 这是一个很大的但是在这里。 ;) 也许你有更好的主意 Spring 让你的 REST api ? Spring 在我看来真的是 "klobby" 而 Vertx.x 真的很流畅。 (我对我的不切实际的意见感到抱歉。)
我在我的应用程序中使用了一种 DI 方法。这意味着:
router.route(HttpMethod.GET,
"/user/login").handler(injector.getInstance(ILoginUser.class));
使用普通的guice框架作为注入器。虽然这只是一个接口,但您可以在必须更改启动服务器的 Verticle 中的某些内容之前进行非常大的更改。 (实际上主要是如果你必须添加或删除路径)
总结:
如果您想使用 Spring 方法,您必须使用反射或使用反射的库。 缺点:Startup-performance,有时有点太神奇了,真的很难找到 errors/debug。 好处:非常容易测试,扩展功能真的非常容易
自己在路径上注册Verticles。 缺点:您必须在 "server"-verticle 上添加/删除路径。 好处:Startup-performance,没有魔法,完全控制发生的事情和时间。
这只是一个简短的总结,很多要点都没有提到。但我希望这能回答你的问题。如果您有一些后续问题,请写信!
杰尔泽,
西米
我最近为 vert.x.
编写了一个简单的 JAX-RS 注释库
它的方法类似于 RestEasy。