Using the Quarkus extension for the Spring Web API
Abstract
Preface
As an application developer, you can use Spring Web annotations to define RESTful services in your Quarkus application.
Providing feedback on Red Hat documentation
We appreciate your feedback on our technical content and encourage you to tell us what you think. If you’d like to add comments, provide insights, correct a typo, or even ask a question, you can do so directly in the documentation.
You must have a Red Hat account and be logged in to the customer portal.
To submit documentation feedback from the customer portal, do the following:
- Select the Multi-page HTML format.
- Click the Feedback button at the top-right of the document.
- Highlight the section of text where you want to provide feedback.
- Click the Add Feedback dialog next to your highlighted text.
- Enter your feedback in the text box on the right of the page and then click Submit.
We automatically create a tracking issue each time you submit feedback. Open the link that is displayed after you click Submit and start watching the issue or add more comments.
Thank you for the valuable feedback.
Making open source more inclusive
Red Hat is committed to replacing problematic language in our code, documentation, and web properties. We are beginning with these four terms: master, slave, blacklist, and whitelist. Because of the enormity of this endeavor, these changes will be implemented gradually over several upcoming releases. For more details, see our CTO Chris Wright’s message.
Quarkus provides a compatibility layer for using annotations from Spring Web to define REST endpoints for your application. This functionality is provided by the quarkus-spring-web
extension as an alternative to using the default JAX-RS annotations to define your REST endpoints.
The Spring compatibility layer in Quarkus does not start a Spring Application Context or execute any infrastructure classes that are provided by Spring (for example, org.springframework.beans.factory.config.BeanPostProcessor
) when you start your application. Quarkus can only read metadata from Spring classes and annotations and parse user code method return types and parameter types that are specific to Spring. However, when you add arbitrary libraries that are part of Spring Framework to your Quarkus application, such libraries will not function properly, because Quarkus is not designed to use them.
You can follow this guide and create the example that uses the Quarkus extension for the Spring Web API, or you can download and view the completed example. To view the completed Quarkus Spring Web example, download it as an archive or clone the Quarkus examples Git repository. You can find the Spring Web example in the spring-web-quickstart
directory.
Chapter 1. Prerequisites
-
Have OpenJDK 11 installed and the
JAVA_HOME
environment variable set to match the path to the directory in which OpenJDK is installed on your system. - Have Apache Maven 3.6.2 or higher installed.
Chapter 2. Creating the Spring Web example Maven project
You can create a new Quarkus project, automatically generate the REST controller class, and add the quarkus-spring-web
dependency with a single command using the Quarkus Maven plugin. You can also update the pom.xml
file and create the REST controller class and the REST controller test class manually.
Procedure
Use one of the following approaches that are shown shown in this section to create your Quarkus Spring Web example Maven project:
If you do not have a Maven project, you can create a new Maven project using the Quarkus Maven plugin. Enter the following command to:
- Create the Maven project directory structure
-
Create the
org.acme.spring.web.GreetingController
class that defines a REST endpoint for your application Import the
quarkus-spring-web
extensionYou must replace
<project_name>
with the name of the directory that contains your project files.mvn io.quarkus:quarkus-maven-plugin:1.11.7.Final-redhat-00009:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=<project_name> \ -DclassName="org.acme.spring.web.GreetingController" \ -Dpath="/greeting" \ -Dextensions="spring-web"
-
If you already have a Quarkus Maven project, you must add the
quarkus-spring-web
extension to it using the command line:
Navigate to the root directory of your project:
cd <project_name>
Add the
quarkus-spring-web
extension to thepom.xml
file of your project:./mvnw quarkus:add-extension -Dextensions="spring-web"
With this command you add the following entry to your
pom.xml
file:pom.xml
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-spring-web</artifactId> </dependency>
Chapter 3. Creating the main class and test class for GreetingController
When you create your project on the command line, the Quarkus Maven plugin automatically generates the GreetingController
class file with Spring Web annotations that defines the REST endpoint and a class file that contains the unit test for GreetingController
.
Procedure
Create the
src/main/java/org/acme/spring/web/GreetingController.java
file that contains the following code.src/main/java/org/acme/spring/web/GreetingController.java
package org.acme.spring.web; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/greeting") public class GreetingController { @GetMapping public String hello() { return "Hello Spring"; } }
Create the
src/test/java/org/acme/spring/web/GreetingControllerTest.java
file that contains the following code.src/test/java/org/acme/spring/web/GreetingControllerTest.java
package org.acme.spring.web; import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.is; @QuarkusTest public class GreetingControllerTest { @Test public void testHelloEndpoint() { given() .when().get("/greeting") .then() .statusCode(200) .body(is("Hello Spring")); } }
Chapter 4. Compiling and starting your Spring Web example
Compile and start your example application using the Quarkus Maven Plugin. You can also compile and run your application as a native executable.
Procedure
Navigate to the root directory of your project:
cd <project_name>
Run the application in development mode using the Quarkus Maven Plugin:
./mvnw compile quarkus:dev
Navigate to
http://localhost:8080/greeting
Your browser displays the following message:Hello Spring
Chapter 5. Configuring the GreetingController to return a JSON response
The GreetingController
that is automatically generated when you set up your Spring Web example is a simple endpoint that returns a text string as a response. In more complex applications, you might need to configure your REST controller to return a response in JSON format. The following example illustrates how you can configure a Spring RestController
to return JSON content:
Procedure
Expand your
GreetingController
class as shown in the example. The expanded class returns a JSON-formatted response that contains a greeting and a name. Note, that you must import thePathVariable
annotation class from Spring Web to ensure that your configuration works correctly:src/main/java/org/acme/spring/web/GreetingController.java
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/greeting") public class GreetingController { @GetMapping public String hello() { return "hello"; } @GetMapping("/{name}") public Greeting hello(@PathVariable(name = "name") String name) { return new Greeting("hello " + name); } public static class Greeting { private final String message; public Greeting(String message) { this.message = message; } public String getMessage(){ return message; } } }
When you make changes to your REST endpoint, you must also update the class file that contains the unit tests for your REST endpoint:
src/test/java/org/acme/spring/web/GreetingControllerTest.java
package org.acme.spring.web; import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.is; @QuarkusTest public class GreetingControllerTest { @Test public void testHelloEndpoint() { given() .when().get("/greeting/quarkus") .then() .statusCode(200) .body("message", is("hello quarkus")); } }
Note, that when you use the Spring Web compatibility layer in Quarkus, the com.fasterxml:jackson.core dependency is automatically added to the classpath of your application and configured.
Chapter 6. Enabling OpenAPI and Swagger-UI support in your Spring Web example
You can add support for generating OpenAPI schema documents of your REST endpoints with Swagger-UI to your application by adding the quarkus-smallrye-openapi
extension.
Procedure
Enter the following command to add the
quarkus-smallrye-openapi
extension as a dependency of your Spring Web example. Adding the extension is enough to generate a basic OpenAPI schema document from your REST Endpoints:./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-smallrye-openapi"
Entering the command adds the following dependency to your
pom.xml
:pom.xml
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-openapi</artifactId> </dependency>
Enter the following command to obtain the schema document from the
/q/openapi
:curl http://localhost:8080/q/openapi
You receive a response with the generated OpenAPI schema document in YAML format:
--- openapi: 3.0.3 info: title: Generated API version: "1.0" paths: /greeting: get: responses: "200": description: OK content: text/plain: schema: type: string /greeting/{name}: get: parameters: - name: name in: path required: true schema: type: string responses: "200": description: OK content: application/json: schema: $ref: '#/components/schemas/Greeting' components: schemas: Greeting: type: object properties: message: type: string
Chapter 7. Adding MicroProfile OpenAPI annotations to your REST controller code
You can add MicroProfile OpenAPI annotations to your rest controller code to generate a more detailed OpenAPI schema for your rest endpoints.
Procedure
Add the
@OpenApiDefinition
annotation at the class level of yourGreetingController
. Include the data that is shown in the example in the annotation:@OpenAPIDefinition( info = @Info( title="Greeting API", version = "1.0.1", contact = @Contact( name = "Greeting API Support", url = "http://exampleurl.com/contact", email = "techsupport@example.com"), license = @License( name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0.html")) )
Annotate your endpoint definitions using the
@Tag
annotation. Give a name and a description for each endpoint:@Tag(name = "Hello", description = "Just say hello") @GetMapping(produces=MediaType.TEXT_PLAIN_VALUE) public String hello() { return "hello"; } @GetMapping(value = "/{name}", produces=MediaType.APPLICATION_JSON_VALUE) @Tag(name = "Hello to someone", description = "Just say hello to someone") public Greeting hello(@PathVariable(name = "name") String name) { return new Greeting("hello " + name); }
The data that you provided in the annotations appears in the generated OpenAPI schema:
openapi: 3.0.3 info: title: Greeting API contact: name: Greeting API Support url: http://exampleurl.com/contact email: techsupport@example.com license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.1 tags: - name: Hello description: Just say hello - name: Hello to someone description: Just say hello to someone paths: /greeting: get: tags: - Hello responses: '200': description: OK content: text/plain: schema: type: string /greeting/{name}: get: tags: - Hello to someone parameters: - name: name in: path required: true schema: type: string responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Greeting' components: schemas: Greeting: type: object properties: message: type: string
Chapter 8. Overview of Spring Web annotations supported in Quarkus
The Spring compatibility layer in Quarkus supports a limited subset of features that Spring Web provides. Specifically, Quarkus supports only the REST-related annotations from Spring Web, for example, @RestController
, but not @Controller
.
Quarkus supports the following annotations from Spring Web:
Chapter 9. Overview of Spring Web annotations and their JAX-RS equivalents
The following table shows how Spring Web annotations can be converted to JAX-RS annotations.
Table 9.1. Spring Web annotations and their JAX-RS equivalents
Spring | JAX-RS | Notes |
---|---|---|
|
There is no equivalent in JAX-RS. Annotating a class with | |
|
| |
|
| |
|
| |
|
| |
|
| |
| No equivalent in JAX-RS. Method parameters corresponding to the body of the request are handled in JAX-RS without requiring any annotation. | |
| No equivalent in JAX-RS. | |
| No equivalent in JAX-RS. | |
|
No equivalent annotation in JAX-RS. Exceptions are handled by implementing |
Chapter 10. Controller method parameter types supported in Quarkus
In addition to the method parameters that can be annotated with the appropriate Spring Web annotations from the previous table, javax.servlet.http.HttpServletRequest
and javax.servlet.http.HttpServletResponse
are also supported. For this to function however, users need to add the quarkus-undertow
dependency.
Chapter 11. Controller method return types supported in Quarkus
The following method return types are supported when using Spring Web on Quarkus:
- Primitive types
- String (Used as a literal. Quarkus does not support Spring MVC view)
- POJO classes that are serialized using JSON
-
org.springframework.http.ResponseEntity
Chapter 12. Exception handler method parameter types supported in Quarkus
The Quarkus extension for Spring Web API supports the following exception handler method parameter types. (The order in which the types are listed is arbitrary and does not reflect the order of preference in which individual parameter types should be used):
-
An exception argument: declared as a general
Exception
or as a more specific exception. This also serves as a mapping hint if the annotation itself does not specify the exception types using itsvalue()
. -
Request or response objects (or both) (typically from the Servlet API). You can choose any specific request or response type, for example
ServletRequest
orHttpServletRequest
. You must add thequarkus-undertow
dependency to your project to use Servlet API.
Other parameter types mentioned in the Spring ExceptionHandler
Java API documentation are not supported in Quarkus
Chapter 13. Exception handler method return types supported in Quarkus
The following method return types are supported when using Spring Web in Quarkus:
-
org.springframework.http.ResponseEntity
-
java.util.Map
Other return types mentioned in the Spring ExceptionHandler
Java API documentation are not supported in Quarkus.
Chapter 14. Additional resources
Revised on 2021-06-22 11:05:53 UTC