Enterprise Java

Swagger Core Tutorial

In this article, we will see what Swagger Core is and what it is used for.

1. Introduction

The OpenAPI specification defines the standard of describing HTTP API for any project. This is programming-language agnostic. This helps humans and computers to know about the System/API without the need to look into the code. If the specification is properly implemented it helps a consumer to understand the interaction with the remote system effectively without much hassle.

OpenAPI specification can be compared to an Interface in Java. Interfaces in Java define the contract between the client and the server. It tells the caller what it needs to send and the expected value which will be returned. This helps the caller to reduce the guesswork. Similarly, OpenAPI is a specification that defines how to document your HTTP API so that the consumer of your API has to do minimal guesswork.

One of the big use cases for a machine-readable API definition is to automatically generate the Client code. The OpenAPI documents are generally described in YAML or JSON. The best part is that these documents can be created statically or generated at runtime. One this to note is that OpenAPI can not be integrated with all the available HTPP API implementations – but they are available for RESTful HTTP Apis. The current version of OpenAPI specification is 3.1.0.

2. Swagger Core

Swagger Core is an open-source Java implementation of the Swagger/OpenAPI specification. Swagger uses Maven for build and deployment and its artifacts are available at Maven Central. Integrating swagger-core into a JAX-RS application can be as easy as adding its dependency to the project POM:

<dependency>
  <groupid>io.swagger.core.v3</groupid>
  <artifactid>swagger-jaxrs2</artifactid>
  <version>2.1.1</version>
</dependency>
<dependency>
  <groupid>io.swagger.core.v3</groupid>
  <artifactid>swagger-jaxrs2-servlet-initializer</artifactid>
  <version>2.1.1</version>
</dependency>

Consider a simple JAX-RS application with an endpoint like below:

@Path("/customer")

public class CustomerResource {

  @GET
  @Path("/customers/{customerId}")
  @Produces("application/json")
  public Customer getCustomer(@PathParam("customerId") Long customerId) {
      // return Customer details
  }

  @POST
  @Consumes("application/json")
  public Response addCustomer(
      @Parameter(description = "New customer details", required = true) Customer newCustomer) {
    // add new customer
    return Response.ok().entity("SUCCESS").build();
  }
}

Just by adding the dependencies, an endpoint <baseUrl>/<contextRoot>/openapi.json is activated, exposing the OpenAPI definition of the app APIs serialized as json or yaml, as resolved by swagger-core processing JAX-RS resources defined in the application. If you hit this endpoint your response will look similar to:

openapi: 3.0.1
paths:
  /sample/customer/{customerId}:
    get:
      operationId: getCustomer
      parameters:
      - name: customerId
        in: path
        required: true
        schema:
          type: integer
          format: int64
      responses:
        default:
          description: default response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
            application/xml:
              schema:
                $ref: '#/components/schemas/Customer'
  /sample/customer:
    post:
      operationId: addCustomer
      requestBody:
        description: New customer details
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Customer'
        required: true
      responses:
        default:
          description: default response
          content:
            application/json: {}
            application/xml: {}
components:
  schemas:
    Tag:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
      xml:
        name: Tag
    Customer:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tags:
          type: array
          xml:
            wrapped: true
          items:
            $ref: '#/components/schemas/Tag'
      xml:
        name: Customer

While the Swagger resolver mechanism is able to analyze resource classes structure and various annotations there are cases where metadata is simply not available (for example determining the response schema of an operation, when the resource method is returning an instance of JAX-RS Response instead of a model POJO) and/or we want to completely customize the definition. To handle this and other cases, and to be able to have full control over the resolved API definition, usage of Swagger annotations comes in handy.

Annotations can be applied to resource classes and whatever model POJOs (particularly used in this context is the @Schema annotation. You can refer to the full list of available annotations here.

Once an API definition is available, you might want to visualize it in a nice UI, and interact with it, for example testing the endpoint with an actual call. Such functionality is provided by swagger-UI which is nicely integrated with swagger-core

3. Conclusion

In this article, we learned about OpenAPI specifications. We then looked into how to implement this specification using Swagger. We also discussed a working example and saw how the swagger-API response to a simple REST API will look like. Please note that the above example uses the default configuration, you can provide your own configuration as well. To do that you will need to create a file named openapi.yaml or openapi-configuration.yaml in the classpath of your application.

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button