Migrating to Quarkus REST (formerly RESTEasy Reactive)
大多数情况下,从 RESTEasy Classic 迁移到 Quarkus REST(以前称为 RESTEasy Reactive)非常简单,但有少数情况需要引起注意。本文档提供了一个列表,列出迁移尝试者应该注意的问题。
Migrating from RESTEasy Classic to Quarkus REST (formerly RESTEasy Reactive) is straightforward in most cases, however there are a few cases that require some attention. This document provides a list of issues users attempting the migration should be aware of.
Quarkus REST 的参考文档可以在 here 中找到。 |
The reference documentation of Quarkus REST can be found here. |
Server
Quarkus REST 的服务器部分( quarkus-rest
及其依赖项)提供了 Jakarta REST 规范的实现,但利用了 Quarkus 的构建时间处理功能和 Vert.x 提供的统一 I/O 模型。
The server part of Quarkus REST (quarkus-rest
and its dependencies) provide an implementation of the Jakarta REST specification, but leverage Quarkus' build time processing
and the unified I/O model provided by Vert.x.
Dependencies
下表将旧版 RESTEasy 依赖性与新的 Quarkus REST 依赖性进行匹配。
The following table matches the legacy RESTEasy dependencies with the new Quarkus REST ones.
Legacy | Quarkus REST |
---|---|
|
|
|
|
|
|
|
|
|
|
|
The |
Annotations
Quarkus REST 不支持 org.jboss.resteasy.annotations
包下的各种自定义注释。
Quarkus REST does not support the various custom annotation under the org.jboss.resteasy.annotations
package.
下表将旧版 RESTEasy 注释与新的 Quarkus REST 注释进行匹配。
The following table matches the legacy RESTEasy annotations with the new Quarkus REST ones.
Legacy | Quarkus REST | Comments |
---|---|---|
|
|
This annotation is not necessary when the path part matches the method parameter name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
前一个表不包括 |
The previous table does not include the |
Jakarta REST providers
虽然 Quarkus REST 提供了与 RESTEasy Classic 相同的规范兼容的行为,但它在运行时不包含相同的精确提供程序实现。
Although Quarkus REST provides the same spec compliant behavior as RESTEasy Classic does, it does not include the same exact provider implementations at runtime.
提供程序的差异可能会导致不同行为的最常见情况是包含的`jakarta.ws.rs.ext.ExceptionMapper`实现。要查看应用程序中包含哪些类,请以开发模式启动应用程序,然后导航至[role="bare"][role="bare"]http://localhost:8080/q/dev-ui/io.quarkus.quarkus-rest/exception-mappers。
The most common case where the difference in providers might result in different behavior, is the included jakarta.ws.rs.ext.ExceptionMapper
implementations. To see what classes are included in the application, launch the application in dev mode and navigate to [role="bare"]http://localhost:8080/q/dev-ui/io.quarkus.quarkus-rest/exception-mappers.
Service Loading
RESTEasy Classic 支持使用 Java 的服务加载器在构建时确定提供程序。为了确保在构建时确定所有提供程序,Quarkus REST 不支持此功能。相反,建议在应用程序依赖项中具有提供程序的用户使用 CDI 指南的Bean Discovery部分中描述的一种方法对这些依赖项进行索引。
RESTEasy Classic supports determining providers at build time using Java’s Service Loader. In order to ensure that all providers are determined at build time, Quarkus REST does not support this feature. Instead, users that have providers in application dependencies are encouraged to index those dependencies using one of the methods described in the Bean Discovery section of the CDI guide.
Multipart support
Quarkus REST 中的 HTTP 多部分支持*not*不重用与 RESTEasy Classic 相同的类型或注释,因此建议用户阅读参考文档的this部分。
HTTP Multipart support in Quarkus REST does not reuse the same types or annotations as RESTEasy Classic and thus users are encouraged to read this part of the reference documentation.
将多部分资源迁移到 Quarkus REST 的用户应注意配置参数`quarkus.http.limits.max-form-attribute-size`,因为它对每个部分的大小设定了上限。任何部分大小超过此配置值的请求将导致 HTTP 状态代码 413。 |
Users migrating multipart resources to Quarkus REST should be aware of the configuration parameter |
Default media types
Quarkus 在确定 Jakarta REST 方法的媒体类型时使用智能默认值,以便简化常见的用例。quarkus-rest`和`quarkus-resteasy`之间的区别在于当方法返回`String`时使用`text/plain`作为默认媒体类型而不是`text/html
。
Quarkus uses smart defaults when determining the media type of Jakarta REST methods in order to simplify common use cases.
The difference between quarkus-rest
and quarkus-resteasy
is the use of text/plain
as the default media type instead of text/html
when the method returns a String
.
Injection of @SessionScoped
beans
当前不支持`@SessionScoped`bean。如果你确实需要此功能,则需要使用 RESTEasy Classic 而不是 RESTEasy Reactive。
@SessionScoped
beans are currently not supported. Should you really need this functionality, you’ll need to use RESTEasy Classic instead of RESTEasy Reactive.
Servlets
Quarkus REST not 支持 servlet。如果您的项目依赖于 servlet,则必须迁移它们。基于 servlet 的 JAX-RS 实现必须使用 @Context
注释支持这些类型的注入:ServletConfig
,ServletContext
,HttpServletRequest
和 HttpServletResponse
。因为 Quarkus REST 不是基于 servlet 的,所以这些注入将不起作用。
Quarkus REST does not support servlets.
If your project depends on servlets you have to migrate them.
A servlet-based JAX-RS implementation must support injections of these types with the @Context
annotation: ServletConfig
, ServletContext
, HttpServletRequest
and HttpServletResponse
.
Since Quarkus REST is not servlet-based these injections will not work.
即使你依赖于提供接口的扩展(例如`quarkus-undertow`),也不总是很明显这点会失败。例如,如果你编写此内容,则可以编译它,但在调用它时会得到一个异常:
It is not always obvious that this will fail especially if you depend on an extension like quarkus-undertow
which supplies the interfaces.
For example, if you write this you could compile it but get an exception on calling it:
@Path("/reactive")
public class ReactiveResource {
@Context
HttpServletRequest httpServletRequest;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String servletContextPath() {
String contextPath = httpServletRequest.getContextPath();
return "My context path is: " + contextPath;
}
}
第三方库也是如此。如果它们碰巧依赖于 servlet,则需要找到它们的迁移路径。
The same is true for your third-party libraries. If they happen to depend on servlets you need to find a migration path for them.
Log authentication and authorization failures
Quarkus REST 端点安全检查在调用CDI interceptors之前执行。记录 Quarkus Security 身份验证异常的最安全方法是确保启用了主动身份验证并使用 Vert.x HTTP 路由故障处理程序。有关更多信息,请参阅主动身份验证指南的Customize authentication exception responses部分。
The Quarkus REST endpoint security checks are performed before CDI interceptors are invoked. The safest approach to log Quarkus Security authentication exceptions is to ensure that proactive authentication is enabled and to use Vert.x HTTP route failure handlers. For more information, see the Customize authentication exception responses section of the Proactive authentication guide.
Client
REST 客户端(quarkus-rest-client`及其依赖项)取代了基于 RESTEasy Classic 的旧版`quarkus-resteasy-client
,并利用 Quarkus 的构建时间处理和 Vert.x 提供的统一 I/O 模型。
The REST Client (quarkus-rest-client
and its dependencies) replaces the legacy RESTEasy Classic-based quarkus-resteasy-client
and leverages Quarkus' build time processing
and the unified I/O model provided by Vert.x.
Dependencies
下表将旧版基于 RESTEasy Classic 的 REST 客户端依赖项与新的 REST 客户端依赖项进行匹配。
The following table matches the legacy RESTEasy Classic-based REST Client dependencies with the new REST Client ones.
Legacy | Quarkus REST |
---|---|
|
|
|
|
|
|
|
|
|
No replacement, natively supports Mutiny |
Keycloak admin client
在使用`quarkus-rest-client`时,用户可以使用`quarkus-keycloak-admin-rest-client`通过利用 REST 客户端来管理目标 Keycloak 实例。
When using quarkus-rest-client
, users can use the quarkus-keycloak-admin-rest-client
to administer the target Keycloak instance
by leveraging the rest client.
然而,在使用`quarkus-resteasy-client`时,用户必须使用`quarkus-keycloak-admin-resteasy-client`来访问相同的功能并使用基于 RESTEasy Classic 的旧版 REST 客户端。
When using quarkus-resteasy-client
however, users must use quarkus-keycloak-admin-resteasy-client
to access the same functionality
and use the legacy RESTEasy Classic-based REST Client.
OIDC
在使用`quarkus-rest-client`时,用户可以使用`quarkus-rest-client-oidc-filter`extension 从 OpenID Connect 和 OAuth 2.0 兼容授权服务器获取和刷新访问令牌。
When using quarkus-rest-client
, users can use the quarkus-rest-client-oidc-filter
extension to acquire and refresh access tokens from OpenID Connect and OAuth 2.0 compliant Authorization Servers.
然而,在使用`quarkus-resteasy-client`时,用户必须使用`quarkus-resteasy-client-oidc-filter`来访问相同的功能。
When using quarkus-resteasy-client
however, users must use quarkus-resteasy-client-oidc-filter
to access the same functionality.
同样,`quarkus-rest-client-oidc-token-propagation`允许传统 REST 的用户传播当前的`Bearer`或`Authorization Code Flow`访问令牌。
Similarly, quarkus-rest-client-oidc-token-propagation
allows user of the legacy REST to propagate the current Bearer
or Authorization Code Flow
access tokens.
然而,在使用`quarkus-resteasy-client`时,用户必须使用`quarkus-resteasy-client-oidc-token-propagation`来访问相同的功能。
When using quarkus-resteasy-client
however, users must use quarkus-resteasy-client-oidc-token-propagation
to access the same functionality.
Custom extensions
这是一个高级部分,仅需要由开发自定义扩展的用户阅读,这些扩展依赖于 Jakarta REST 和/或 REST 客户端功能。
This is an advanced section that only needs to be read by users who have developed custom extensions that depend on Jakarta REST and / or REST Client functionality.
Dependencies
首要顾虑是自定义扩展应明确依赖于 Quarkus REST 还是同时支持 RESTEasy 组件,并由用户决定。如果该扩展是一些通用扩展,那么可能合理选择后者选项,而当特定用户/应用程序集使用自定义扩展时,前者选项最易于采纳。
A first concern is whether custom extensions should depend on Quarkus REST explicitly, or alternatively support both RESTEasy flavors and leave it to the user to decide. If the extension is some general purpose extension, it probably makes sense to choose the latter option, while the former option is easiest to adopt when the custom extension is used by a specific set of users / applications.
在选择支持这两个扩展时,该自定义扩展的部署模块通常将依赖于 SPI 模块——quarkus-jaxrs-spi-deployment
、quarkus-resteasy-common-spi
、quarkus-rest-spi-deployment
,而运行时模块将对 RESTEasy 两个组件的运行时模块存在 optional
依赖关系。
When opting for supporting both extensions, the deployment module of the custom extension will usually depend on the SPI modules - quarkus-jaxrs-spi-deployment
, quarkus-resteasy-common-spi
, quarkus-rest-spi-deployment
,
while the runtime modules will have optional
dependencies on the runtime modules of both RESTEasy flavors.
一些很好的例子说明 Quarkus 如何在核心存储库中使用此策略来支持这两个 RESTEasy 组件,可参见 [此处]([role="bare"][role="bare"]https://github.com/quarkusio/quarkus/pull/21089) 和 [此处]([role="bare"][role="bare"]https://github.com/quarkusio/quarkus/pull/20874)。
A couple good examples of how Quarkus uses this strategy to support both RESTEasy flavors in the core repository can be seen [here]([role="bare"]https://github.com/quarkusio/quarkus/pull/21089) and [here]([role="bare"]https://github.com/quarkusio/quarkus/pull/20874).
通常,支持这两个组件不需要该自定义扩展的两个不同版本。这样的选择只在扩展使用者(即 Quarkus 应用程序)希望不必自己选择 RESTEasy 版本时才是严格需要的。
In general, it should not be needed to have two different versions of the custom extension to support both flavors. Such a choice is only strictly necessary if it is desired for the extension consumers (i.e. Quarkus applications) to not have to select a RESTEasy version themselves.
Resource and Provider discovery
在其运行时模块中包含 Jakarta REST 资源、提供程序或 REST 客户端接口且依赖于 Jandex 索引以发现它们的自定义扩展(例如,因为它们有一个空的 META-INF/beans.xml
文件),不必执行任何其他设置以使 Quarkus REST 发现它们。
Custom extensions that contain Jakarta REST Resources, Providers or REST Client interfaces in their runtime modules and depend on Jandex indexing for
their discovery (for example because they have an empty META-INF/beans.xml
file) don’t have to perform any additional setup to make
these discoverable by Quarkus REST.
Provider registration via Build Items
通过构建项目使用 io.quarkus.resteasy.common.spi.ResteasyJaxrsProviderBuildItem
构建项目在 RESTEasy Classic 中注册提供程序。然而,使用 Quarkus REST 时,扩展需要使用特定的构建项目,如 io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem
和 io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem
。
Extensions that register providers via build items use the io.quarkus.resteasy.common.spi.ResteasyJaxrsProviderBuildItem
build item in RESTEasy Classic.
With Quarkus REST however, extensions need to use specific build items, such as io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem
and io.quarkus.resteasy.reactive.spi.MessageBodyWriterBuildItem
.
REST Client
作为使用 RESTEasy 客户端的 Quarkus 应用程序一部分运行的任何代码,都可以安全地使用 REST 客户端,因为它在应用程序的静态初始化阶段已经配置了所有必要的设置。
Any code that is run as part of a Quarkus application that used the RESTEasy Client, can safely use the REST Client, as all necessary setup for it has been done at the application’s static-init phase.