Quarkus中RESTEasy Reactive集成合并master分支

作者:kl 时间:2023-06-07 14:20:45 

Quarkus中RESTEasy Reactive集成合并master分支

前言

Quarkus和RESTEasy团队非常高兴地宣布了Quarkus中的RESTEasy Reactive集成已进入master分支,并将成为下一个Quarkus 1.11发行版的一部分。我们期待每个人对其进行测试。并为我们提供尽可能多的反馈。以典型的Quarkus方式,该项目可作为一组新的扩展使用。这是一个非常令人兴奋的消息,所以博主用自己蹩脚的英语+google翻译翻译了官方的公告,迫不及待的想要和大家分享。

它是什么?

正如您可能从名称中猜到的那样,该工作是从头开始编写的新JAX-RS实现,可在我们的通用Vert.x层上工作,因此具有完全的反应性,同时还与Quarkus紧密集成,因此移动了很多特定于框架的工作(例如注释扫描和元模型生成)以建立时间。

为什么非常重要?

最简单的答案是,您可以继续利用广泛使用且功能强大的JAX-RS API为应用程序公开REST层,同时显着提高应用程序可以实现的最大吞吐量。该应用程序还应该稍微加快启动速度,并占用更少的内存。

我们的基准测试表明,此新扩展的可测量性能几乎与我们使用Quarkus的Reactive Routes API(它本身是一个非常有趣的API,但通常级别较低)所达到的性能相同,更不用说这是开发人员需要学习的新API)。

此外,将我们的结果与提供基于注释的REST层的其他竞争企业Java框架进行比较时,根据基准,Quarkus提供的吞吐量是原来的两倍。

还有什么其他好处?

好像熟悉的API和新扩展的改进的运行时特性还不够,我们添加了一些真正令人兴奋且方便的新功能(这些功能不是JAX-RS规范的一部分),这些功能是社区所要求的,或者我们觉得可以改善开发人员的体验,并减轻某些规范的毛病。这些新功能是:

  • 默认不阻塞:现在,默认情况下,所有端点都在IO线程上运行。您可以@Blocking用来更改它。

  • 计分系统:在开发人员模式启动时,该应用程序将为您显示端点列表,以及性能得分,告诉您为什么端点比最佳版本慢。这有助于弄清楚如何提高REST性能。

新的请求/响应过滤器设计

JAX-RS过滤器需要实现一个接口并将上下文对象作为字段注入,这既昂贵又不灵活。基于我们在Quarkus构建系统中的成功,现在过滤器只是带有注释的方法,并且会自动注入任何参数:

public class CustomContainerRequestFilter {
  @ServerRequestFilter
  public void whatever(UriInfo uriInfo, HttpHeaders httpHeaders, ContainerRequestContext requestContext) {
      String customHeaderValue = uriInfo.getPath() + "-" + httpHeaders.getHeaderString("some-input");
      requestContext.getHeaders().putSingle("custom-header", customHeaderValue);
  }
}

此外,如果过滤器需要执行阻止操作,则它们可以返回Uni并且RESTEasy Reactive在执行过滤器时不会阻止事件循环线程。
最后,尽管我们还没有完成,但是可以很容易地将此方法扩展到其他类型的JAX-RS Provider,从而完全不需要@Context在其代码中使用。

新*Param注解

这些注释意味着要用来代替JAX-RS @PathParam,@QueryParam等注释,而不必需要指定一个名称。我们选择不重用相同的批注名称的原因是为了避免与JAX-RS或其他EE规范冲突:

@POST
@Path("params/{p}")
public String params(@RestPath String p,
                   @RestQuery String q,
                   @RestHeader int h,
                   @RestForm String f,
                   @RestMatrix String m,
                   @RestCookie String c) {
  return "params: p: " + p + ", q: " + q + ", h: " + h + ", f: " + f + ", m: " + m + ", c: " + c;
}

更简单的参数和上下文注入

使用RESTEasy Reactive,您甚至不需要使用,@PathParam或者@RestPath您的参数与path参数具有相同的名称,并且类似地,您可以跳过@Context所有已知的上下文类型,这使它更加简单:

@POST
@Path("params/{p}")
public String params(String p, UriInfo info) {
  return "params: p: " + p + ", info: " + info;
}

新的最佳消息正文阅读器/编写器

如果在为端点提供服务时未调用任何筛选器和 * ,则可以使用更高效的消息正文编写器,这些编写器直接写入vert.x,并且不需要反射和注释:

@Provider
public class ServerVertxBufferMessageBodyWriter extends VertxBufferMessageBodyWriter
      implements ServerMessageBodyWriter{
  @Override
  public boolean isWriteable(Class type, ResteasyReactiveResourceInfo target, MediaType mediaType) {
      return true;
  }
  @Override
  public void writeResponse(Buffer buffer, ServerRequestContext context) {
      context.serverResponse().end(buffer.getBytes());
  }
}

默认内容类型

返回String的端点默认为产生文本/纯文本。我们计划对JSON和其他类型执行相同的操作。

CDI整合

通过JAX-RS的@Context进行的所有注入都委托给Arc。这为用户提供了Arc带给Quarkus所有其他部分的构建时间注入的好处。

每类异常映射器

在JAX-RS规范中,无法对特定的JAX-RS资源类以不同的方式处理异常-所有异常映射都是以全局方式完成的。但是在RESTEasy Reactive中,您可以简单地执行以下操作:

@Path("first")
public class FirstResource {
  @GET
  @Produces("text/plain")
  public String throwsVariousExceptions(@RestQuery String name) {
      if (name.startsWith("IllegalArgument")) {
          throw new IllegalArgumentException();
      } else if (name.startsWith("IllegalState")) {
          throw new IllegalStateException("IllegalState");
      } else if (name.startsWith("My")) {
          throw new MyException();
      }
      throw new RuntimeException();
  }
  @ServerExceptionMapper({ IllegalStateException.class, IllegalArgumentException.class })
  public Response handleIllegal() {
      return Response.status(409).build();
  }
  @ServerExceptionMapper(MyException.class)
  public Response handleMy(SimpleResourceInfo simplifiedResourceInfo, MyException myException,
          ContainerRequestContext containerRequestContext, UriInfo uriInfo, HttpHeaders httpHeaders, Request request) {
      return Response.status(410).entity(uriInfo.getPath() + "->" + simplifiedResourceInfo.getMethodName()).build();
  }
}

为了自定义某些资源类的异常处理。还要注意,@ServerExceptionMapper可以像JAX-RS使用那样以全局方式处理异常ExceptionMapper。为此,只需使用注释不属于Resource类的方法@ServerExceptionMapper。

其他扩展程序也可以使用吗?

绝对!与现有quarkus-resteasy扩展集成的扩展也与quarkus-resteasy-active扩展集成。因此,您可以继续使用CDI,Security,Metrics,JSON,Qute,Bean Validation,OpenAPI, 并享受开箱即用和完善的开发经验。

该如何尝试?

该项目已降落在Quarkus主分支,所以,如果你渴望尝试一下,你就必须按照从源代码编译Quarkus这和使用遵循正确BOM和版本此。可用的RESTEasy Reactive扩展为:

quarkus-resteasy-reactive

quarkus-resteasy-reactive-jackson

quarkus-resteasy-reactive-jsonb

quarkus-resteasy-reactive-qute

些扩展等效于现有的quarkus-resteasy *扩展,因此只需在应用程序中从quarkus-resteasy-jackson切换到quarkus-resteasy-reactive-jackson,即可让您尝试通过Jackson集成进行RESTEasy Reactive。
此外,如果需要使用JAX-RS客户端,则可以使用quarkus-jaxrs-client扩展(这不是声明性的MicroProfile REST客户端,而是JAX-RS规范指定的程序化客户端)。

应该注意什么?

首先要注意的是,目前暂时将这组扩展视为实验性的。尽管该项目几乎通过了JAX-RS TCK的全部,但它只是第一个发行版,因此请记住,它可能比典型的经过战斗的库具有更多的错误,而某些新的API和SPI可能会损坏。尽管这是第一个发行版,但我们确实预想这项工作将在不久的将来成为Quarkus的默认REST层。

如新功能部分所述,默认情况下,请求是在事件循环线程上处理的。这样可以确保最大的吞吐量,但是也意味着不应在这些线程上执行任何阻塞工作。如果您使用Blocking IO(例如,通过使用Hibernate Panache访问数据库),请确保@Blocking在方法或类上使用注释。这将确保该请求将在工作线程上得到服务。不用说,我们也非常有兴趣听到您对此默认设置的反馈。

尚无文档。文档将在1.11正式版之前添加,并将逐步增强。该电子邮件应包含您入门所需的所有信息,但是如果您遇到任何麻烦,我们可以在任何常用渠道(Zulip聊天,邮件列表,GitHub问题,StackOverflow)上为您提供帮助。

缺少哪些JAX-RS功能?

我们决定专注于现代REST层上大多数用户的需求,而不是实现JAX-RS TCK所需的每个功能。因此,就这一点而言,RESTEasy Reactive中不提供XML支持,同时也不支持该规范的各种奥秘功能

例如:

javax.activation.DataSource

javax.annotation.ManagedBean

javax.ws.rs.core.StreamingOutput

此外,值得注意的是,第一个发行版将不包含基于新的JAX-RS客户端(具有专用扩展)的MicroProfile REST客户端的实现。这很可能在不久的将来改变。

下一步计划是什么?

尽管新的扩展将随常规的1.11版本一起提供,但我们正在考虑1.11.0.Alpha1发布一个版本,以使您尽可能容易地尝试新的扩展并提供早期反馈。我们非常期待听到您在Quarkus中使用RESTEasy Reactive的想法和经验,并计划充分利用它来进一步改进该项目。

来源:http://www.kailing.pub/article/index/arcid/318.html

标签:Quarkus,RESTEasy,Reactive,master
0
投稿

猜你喜欢

  • Winform 控件优化LayeredWindow无锯齿圆角窗体

    2021-12-07 22:54:17
  • Android 中解决Viewpage调用notifyDataSetChanged()时界面无刷新的问题

    2022-11-11 22:21:50
  • 详解SpringBoot通用配置文件(不定时更新)

    2022-12-01 09:07:04
  • Android 后台发送邮件示例 (收集应用异常信息+Demo代码)

    2022-06-24 16:31:06
  • Kotlin 接口与 Java8 新特性接口详解

    2023-09-10 01:10:45
  • Java中的synchronized关键字

    2023-07-28 18:39:26
  • C#将布尔类型转换成字节数组的方法

    2023-06-21 15:30:16
  • Android控件PopupWindow模仿ios底部弹窗

    2023-03-09 20:42:10
  • 创建execl导入工具类的步骤

    2022-03-11 11:41:09
  • mybatis-plus使用问题小结

    2023-10-30 06:45:58
  • c#中SAPI使用总结——SpVoice的使用方法

    2022-02-20 09:50:07
  • 利用源码编译Android系统的APK和可执行命令的方法

    2023-12-22 13:09:46
  • android实现简单音乐播放器

    2021-06-28 22:07:26
  • Spring Boot加密配置文件特殊内容的示例代码详解

    2023-09-18 08:47:24
  • C#随机生成Unicode类型字符串

    2023-12-05 08:42:29
  • Android之在linux终端执行shell脚本直接打印当前运行app的日志的实现方法

    2021-06-12 23:41:08
  • C++深入细致探究二叉搜索树

    2021-12-31 00:09:24
  • springboot中使用rabbitt的详细方法

    2023-06-17 09:57:43
  • Android自定义滑动解锁控件使用详解

    2022-08-20 05:36:38
  • 详解SpringBoot启动代码和自动装配源码分析

    2021-10-18 08:49:21
  • asp之家 软件编程 m.aspxhome.com