我曾尝试同时使用 Munity API 和 Vertx Route。完整的代码在这里。
我定义了这样的路由器规则。
router.put("/posts/:id").consumes("application/json").handler(BodyHandler.create()).handler(handlers::update);
处理程序实现是这样的。
LOGGER.log(Level.INFO, "\npath param id: {0}\nrequest body: {1}", new Object[]{id, body});
var form = fromJson(body, PostForm.class);
this.posts.findById(UUID.fromString(id))
.onFailure(PostNotFoundException.class).invoke(ex -> rc.response().setStatusCode(404).end())
.map(
post -> {
post.setTitle(form.getTitle());
post.setContent(form.getContent());
return this.posts.update(UUID.fromString(id), post);
}
)
.subscribe()
.with(data -> rc.response().setStatusCode(204).end());
在该findById
方法中,它抛出一个PostNotFoundException
.
public Uni<Post> findById(UUID id) {
return this.client
.preparedQuery("SELECT * FROM posts WHERE id=$1")
.execute(Tuple.of(id))
.map(RowSet::iterator)
// .map(it -> it.hasNext() ? rowToPost(it.next()) : null);
.flatMap(it -> it.hasNext() ? Uni.createFrom().item(rowToPost(it.next())) : Uni.createFrom().failure(PostNotFoundException::new));
}
运行应用程序时,对不存在的 post id 进行更新(通过 HTTP PUT 方法)/posts/postid
,它将按预期打印 404 错误状态,但在此期间会有一些暂停时间。
在另一个处理程序方法中,它调用findById
如下,它运行良好并且在找不到时快速响应。
this.posts.findById(UUID.fromString(id))
.subscribe()
.with(
post -> rc.response().end(toJson(post)),
throwable -> rc.fail(404, throwable)
);