添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

This guide explains how your Quarkus application can expose its API description through an OpenAPI specification and how you can test it via a user-friendly UI named Swagger UI.

In this guide, we create a straightforward REST application to demonstrate how fast you can expose your API specification and benefit from a user interface to test it.

quarkus create app org.acme:openapi-swaggerui-quickstart \
    --extension='rest-jackson' \
    --no-code
cd openapi-swaggerui-quickstart

创建Grade项目,请添加 --gradle 或者 --gradle-kotlin-dsl 参数。

For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.

mvn io.quarkus.platform:quarkus-maven-plugin:3.12.2:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=openapi-swaggerui-quickstart \
    -Dextensions='rest-jackson' \
    -DnoCode
cd openapi-swaggerui-quickstart

创建Grade项目,请添加 -DbuildTool=gradle 或者 -DbuildTool=gradle-kotlin-dsl 参数。

public Fruit(String name, String description) { this.name = name; this.description = description; public class FruitResource { private Set<Fruit> fruits = Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap<>())); public FruitResource() { fruits.add(new Fruit("Apple", "Winter fruit")); fruits.add(new Fruit("Pineapple", "Tropical fruit")); public Set<Fruit> list() { return fruits; @POST public Set<Fruit> add(Fruit fruit) { fruits.add(fruit); return fruits; @DELETE public Set<Fruit> delete(Fruit fruit) { fruits.removeIf(existingFruit -> existingFruit.name.contentEquals(fruit.name)); return fruits;

You can also create a test:

package org.acme.openapi.swaggerui;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import jakarta.ws.rs.core.MediaType;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.containsInAnyOrder;
@QuarkusTest
public class FruitResourceTest {
    @Test
    public void testList() {
        given()
                .when().get("/fruits")
                .then()
                .statusCode(200)
                .body("$.size()", is(2),
                        "name", containsInAnyOrder("Apple", "Pineapple"),
                        "description", containsInAnyOrder("Winter fruit", "Tropical fruit"));
    @Test
    public void testAdd() {
        given()
                .body("{\"name\": \"Pear\", \"description\": \"Winter fruit\"}")
                .header("Content-Type", MediaType.APPLICATION_JSON)
                .when()
                .post("/fruits")
                .then()
                .statusCode(200)
                .body("$.size()", is(3),
                        "name", containsInAnyOrder("Apple", "Pineapple", "Pear"),
                        "description", containsInAnyOrder("Winter fruit", "Tropical fruit", "Winter fruit"));
        given()
                .body("{\"name\": \"Pear\", \"description\": \"Winter fruit\"}")
                .header("Content-Type", MediaType.APPLICATION_JSON)
                .when()
                .delete("/fruits")
                .then()
                .statusCode(200)
                .body("$.size()", is(2),
                        "name", containsInAnyOrder("Apple", "Pineapple"),
                        "description", containsInAnyOrder("Winter fruit", "Tropical fruit"));

Quarkus provides the Smallrye OpenAPI extension compliant with the MicroProfile OpenAPI specification in order to generate your API OpenAPI v3 specification.

You just need to add the openapi extension to your Quarkus application:

quarkus extension add quarkus-smallrye-openapi
Maven
./mvnw quarkus:add-extension -Dextensions='quarkus-smallrye-openapi'
Gradle
./gradlew addExtension --extensions='quarkus-smallrye-openapi'

这会将以下内容添加到你的构建文件中:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-smallrye-openapi")

Now, we are ready to run our application:

quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

Once your application is started, you can make a request to the default /q/openapi endpoint:

$ curl http://localhost:8080/q/openapi
openapi: 3.0.3
info:
  title: Generated API
  version: "1.0"
paths:
  /fruits:
      responses:
          description: OK
          content:
            application/json: {}
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
          description: OK
          content:
            application/json: {}
    delete:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
          description: OK
          content:
            application/json: {}
components:
  schemas:
    Fruit:
      properties:
        description:
          type: string
        name:
          type: string

All of this information (and more) can be included in your Java code by using appropriate OpenAPI annotations on a Jakarta REST Application class. Because a Jakarta REST Application class is not required in Quarkus, you will likely have to create one. It can simply be an empty class that extends jakarta.ws.rs.core.Application. This empty class can then be annotated with various OpenAPI annotations such as @OpenAPIDefinition. For example:

@OpenAPIDefinition(
    tags = {
            @Tag(name="widget", description="Widget operations."),
            @Tag(name="gasket", description="Operations related to gaskets")
    info = @Info(
        title="Example API",
        version = "1.0.1",
        contact = @Contact(
            name = "Example API Support",
            url = "http://exampleurl.com/contact",
            email = "[email protected]"),
        license = @License(
            name = "Apache 2.0",
            url = "https://www.apache.org/licenses/LICENSE-2.0.html"))
public class ExampleApiApplication extends Application {

Another option, that is a feature provided by SmallRye and not part of the specification, is to use configuration to add this global API information. This way, you do not need to have a Jakarta REST Application class, and you can name the API differently per environment.

For example, add the following to your application.properties:

quarkus.smallrye-openapi.info-title=Example API
%dev.quarkus.smallrye-openapi.info-title=Example API (development)
%test.quarkus.smallrye-openapi.info-title=Example API (test)
quarkus.smallrye-openapi.info-version=1.0.1
quarkus.smallrye-openapi.info-description=Just an example service
quarkus.smallrye-openapi.info-terms-of-service=Your terms here
quarkus.smallrye-openapi.info-contact-email=techsupport@example.com
quarkus.smallrye-openapi.info-contact-name=Example API Support
quarkus.smallrye-openapi.info-contact-url=http://exampleurl.com/contact
quarkus.smallrye-openapi.info-license-name=Apache 2.0
quarkus.smallrye-openapi.info-license-url=https://www.apache.org/licenses/LICENSE-2.0.html

This will give you similar information as the @OpenAPIDefinition example above.

@OpenApiFilter(OpenApiFilter.RunStage.BUILD) (1) public class MyBuildTimeFilter implements OASFilter { (2) private IndexView view; public MyBuildTimeFilter(IndexView view) { (3) this.view = view; @Override public void filterOpenAPI(OpenAPI openAPI) { (4) Collection<ClassInfo> knownClasses = this.view.getKnownClasses(); Info info = OASFactory.createInfo(); info.setDescription("Created from Annotated Buildtime filter with " + knownClasses.size() + " known indexed classes"); openAPI.setInfo(info);

Remember that setting fields on the schema will override what has been generated, you might want to get and add to (so modify). Also know that the generated values might be null, so you will have to check for that.

Runtime filters

Runtime filters by default runs on startup (when the final OpenAPI document gets created). You can change runtime filters to run on every request, making the openapi document dynamic. To do this you need to set this propery: quarkus.smallrye-openapi.always-run-filter=true.

Instead of dynamically creating OpenAPI schemas from annotation scanning, Quarkus also supports serving static OpenAPI documents. The static file to serve must be a valid document conforming to the OpenAPI specification. An OpenAPI document that conforms to the OpenAPI Specification is itself a valid JSON object, that can be represented in yaml or json formats.

To see this in action, we’ll put OpenAPI documentation under META-INF/openapi.yaml for our /fruits endpoints. Quarkus also supports alternative OpenAPI document paths if you prefer.

openapi: 3.0.1
info:
  title: Static OpenAPI document of fruits resource
  description: Fruit resources Open API documentation
  version: "1.0"
servers:
  - url: http://localhost:8080/q/openapi
    description: Optional dev mode server description
paths:
  /fruits:
      responses:
          description: OK - fruits list
          content:
            application/json: {}
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
          description: new fruit resource created
          content:
            application/json: {}
    delete:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
          description: OK - fruit resource deleted
          content:
            application/json: {}
components:
  schemas:
    Fruit:
      properties:
        description:
          type: string
        name:
          type: string

By default, a request to /q/openapi will serve the combined OpenAPI document from the static file and the model generated from application endpoints code. We can however change this to only serve the static OpenAPI document by adding mp.openapi.scan.disable=true configuration into application.properties.

Now, a request to /q/openapi endpoint will serve the static OpenAPI document instead of the generated one.

About OpenAPI document paths

Quarkus supports various paths to store your OpenAPI document under. We recommend you place it under META-INF/openapi.yml. Alternative paths are:

By default, when the document is generated, the OpenAPI version used will be 3.0.3. If you use a static file as mentioned above, the version in the file will be used. You can also define the version in SmallRye using the following configuration:

mp.openapi.extensions.smallrye.openapi=3.0.2

This might be useful if your API goes through a Gateway that needs a certain version.

The Operation Id can be set using the @Operation annotation, and is in many cases useful when using a tool to generate a client stub from the schema. The Operation Id is typically used for the method name in the client stub. In SmallRye, you can auto-generate this Operation Id by using the following configuration:

mp.openapi.extensions.smallrye.operationIdStrategy=METHOD

Now you do not need to use the @Operation annotation. While generating the document, the method name will be used for the Operation Id.

Table 1. The strategies available for generating the Operation Id

When building APIs, developers want to test them quickly. Swagger UI is a great tool permitting to visualize and interact with your APIs. The UI is automatically generated from your OpenAPI specification.

The Quarkus smallrye-openapi extension comes with a swagger-ui extension embedding a properly configured Swagger UI page.

Once your application is started, you can go to http://localhost:8080/q/swagger-ui and play with your API.

You can visualize your API’s operations and schemas.

You can also interact with your API in order to quickly test it.

使用 CTRL+C 来停止应用程序。

Styling

You can style the swagger ui by supplying your own logo and css.

To supply your own logo, you need to place a file called logo.png in src/main/resources/META-INF/branding.

This will set the logo for all UIs (not just swagger ui), so in this case also GraphQL-UI and Health-UI (if included).

If you only want to apply this logo to swagger-ui (and not globally to all UIs) call the file smallrye-open-api-ui.png rather than logo.png.

To supply your own css that override/enhance style in the html, you need to place a file called style.css in src/main/resources/META-INF/branding.

This will add that css to all UIs (not just swagger ui), so in this case also GraphQL-UI and Health-UI (if included).

If you only want to apply this style to swagger-ui (and not globally to all UIs) call the file smallrye-open-api-ui.css rather than style.css.

For more information on styling, read this blog entry: https://quarkus.io/blog/stylish-api/

If set, the generated OpenAPI schema documents will be stored here on build. Both openapi.json and openapi.yaml will be stored here if this is set.

Environment variable: QUARKUS_SMALLRYE_OPENAPI_STORE_SCHEMA_DIRECTORY