Back to Guides

Migrating to RESTEasy Reactive

Migrating from RESTEasy Classic to 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.

The reference documentation of RESTEasy Reactive can be found here.

Server

The server part of RESTEasy Reactive (quarkus-resteasy-reactive and its dependencies) provide an implementation of the JAX-RS specification, but leverage Quarkus' build time processing and the unified I/O model provided by Vert.x.

Dependencies

The following table matches the legacy RESTEasy dependencies with the new RESTEasy Reactive ones.

Legacy RESTEasy Reactive

quarkus-resteasy

quarkus-resteasy-reactive

quarkus-resteasy-jackson

quarkus-resteasy-reactive-jackson

quarkus-resteasy-jsonb

quarkus-resteasy-reactive-jsonb

quarkus-resteasy-jaxb

quarkus-resteasy-reactive-jaxb

quarkus-resteasy-qute

quarkus-resteasy-reactive-qute

The quarkus-resteasy-mutiny does not have a corresponding dependency, as RESTEasy Reactive provides Mutiny integration out of the box.

Annotations

RESTEasy Reactive does not support the various custom annotation under the org.jboss.resteasy.annotations package.

The following table matches the legacy RESTEasy annotations with the new RESTEasy Reactive ones.

Legacy RESTEasy Reactive Comments

org.jboss.resteasy.annotations.jaxrs.PathParam

org.jboss.resteasy.reactive.RestPath

This annotation is not necessary when the path part matches the method parameter name

org.jboss.resteasy.annotations.jaxrs.QueryParam

org.jboss.resteasy.reactive.RestQuery

org.jboss.resteasy.annotations.jaxrs.FormParam

org.jboss.resteasy.reactive.RestForm

org.jboss.resteasy.annotations.jaxrs.HeaderParam

org.jboss.resteasy.reactive.RestHeader

org.jboss.resteasy.annotations.jaxrs.CookieParam

org.jboss.resteasy.reactive.RestCookie

org.jboss.resteasy.annotations.jaxrs.MatrixParam

org.jboss.resteasy.reactive.RestMatrix

org.jboss.resteasy.annotations.cache.Cache

org.jboss.resteasy.reactive.Cache

org.jboss.resteasy.annotations.cache.NoCache

org.jboss.resteasy.reactive.NoCache

org.jboss.resteasy.annotations.SseElementType

org.jboss.resteasy.reactive.RestStreamElementType

The previous table does not include the org.jboss.resteasy.annotations.Form annotation because there is no RESTEasy Reactive specific replacement for it. Users are instead encouraged to use the JAX-RS standard javax.ws.rs.BeanParam annotation which is supported on both the server and the client.

JAX-RS providers

Although RESTEasy Reactive provides the same spec compliant behavior as RESTEasy Classic does, it does not include the same exact provider implementations at runtime.

The most common case where the difference in providers might result in different behavior, is the included javax.ws.rs.ext.ExceptionMapper implementations. To see what classes are included in the application, launch the application in dev mode and navigate to http://localhost:8080/q/dev/io.quarkus.quarkus-resteasy-reactive/exception-mappers.

Service Loading

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, RESTEasy Reactive 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

HTTP Multipart support in RESTEasy Reactive does not reuse the same types or annotations as RESTEasy Classic and thus users are encouraged to read this part of the reference documentation.

Users migrating multipart resources to RESTEasy Reactive should be aware of the configuration parameter quarkus.http.limits.max-form-attribute-size, as this poses an upper limit to the size of each part. Any request with a part size exceeding this configuration value will result in HTTP status code 413.

Default media types

Quarkus uses smart defaults when determining the media type of JAX-RS methods in order to simplify common use cases. The difference between quarkus-resteasy-reactive and quarkus-resteasy is the use of text/plain as the default media type instead of text/html when the method returns a String.

Client

The Reactive REST Client (quarkus-rest-client-reactive and its dependencies) replace the legacy quarkus-rest-client but leverage Quarkus' build time processing and the unified I/O model provided by Vert.x.

Dependencies

The following table matches the legacy REST Client dependencies with the new Reactive REST Client ones.

Legacy RESTEasy Reactive

quarkus-rest-client

quarkus-rest-client-reactive

quarkus-rest-client-jackson

quarkus-rest-client-reactive-jackson

quarkus-rest-client-jsonb

quarkus-rest-client-reactive-jsonb

quarkus-rest-client-jaxb

quarkus-rest-client-reactive-jaxb

Keycloak admin client

When using quarkus-rest-client, users can use the quarkus-keycloak-admin-client to administer the target Keycloak instance by leveraging the rest client.

When using quarkus-rest-client-reactive however, users must use quarkus-keycloak-admin-client-reactive to access the same functionality and use the reactive REST Client.

OIDC

When using quarkus-rest-client, users can use the quarkus-oidc-client-filter extensions to acquire and refresh access tokens from OpenID Connect and OAuth 2.0 compliant Authorization Servers.

When using quarkus-rest-client-reactive however, users must use quarkus-oidc-client-filter-reactive to access the same functionality.

Similarly, quarkus-oidc-token-propagation allows user of the legacy REST to propagate the current Bearer or Authorization Code Flow access tokens.

When using quarkus-rest-client-reactive however, users must use quarkus-oidc-token-propagation-reactive to access the same functionality.

Custom extensions

This is an advanced section that only needs to be read by users who have developed custom extensions that depend on JAX-RS and / or REST Client functionality.

Dependencies

A first concern is whether custom extensions should depend on RESTEasy Reactive 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.

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-resteasy-reactive-spi-deployment, while the runtime modules will have optional dependencies on the runtime modules of both RESTEasy flavors.

A couple good examples of how Quarkus uses this strategy to support both RESTEasy flavors in the core repository can be seen [here](https://github.com/quarkusio/quarkus/pull/21089) and [here](https://github.com/quarkusio/quarkus/pull/20874).

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

Custom extensions that contain JAX-RS 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 RESTEasy Reactive.

Provider registration via Build Items

Extensions that register providers via build items use the io.quarkus.resteasy.common.spi.ResteasyJaxrsProviderBuildItem build item in RESTEasy Classic. With RESTEasy Reactive 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

Any code that is run as part of a Quarkus application that used the REST Client, can safely use the Reactive REST Client, as all necessary setup for it has been done at the application’s static-init phase.