Migration from Swagger 2 to OpenAPI 3
Tags: tutorial, openapi, springboot, java
Published: 2022-02-01 07:01:25

![archives](https://cdn-images-1.medium.com/max/2000/0*KF_MRwLdyoVL7jQa.png)

A lot of API are documented using [Swagger](https://swagger.io/), it’s a good thing that API are documented four us dev for understanding how they work and how to call them.
But a lot of these API are documented using Swagger 2, now that [OpenApi](https://swagger.io/specification/) is released ([since 2017, the actual version is the 3.1 and is available since 15/02/2021](https://en.wikipedia.org/wiki/OpenAPI_Specification#Release_dates)) some projects didn’t update their documentation tools, I will try in this article to help you do so.

## What you will need

In order to follow this tutorial, you will need a [REST API](https://medium.com/javarevisited/top-5-books-and-courses-to-learn-restful-web-services-in-java-using-spring-mvc-and-spring-boot-79ec4b351d12?source=---------17------------------), so you can :

* Follow the [tutorial to built your API](https://dev.to/erwanlt/building-a-simple-rest-api-with-springboot-53mc) and the [one to documente it](https://dev.to/erwanlt/documenting-your-api-with-swagger-2-af6)

* Clone the swagger branch of [this repository](https://github.com/ErwanLT/HumanCloningFacilities)

* Having your own API documented using Swagger 2 ready

## Step 1 : getting ride of SpringFox dependencies

When we first implemented our Swagger, we add these dependencies to have

* The json generated at [http://localhost:8080/v2/api-docs](http://localhost:8080/v2/api-docs)

* The UI at [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html)

* The Bean Validation
{% gist https://gist.github.com/ErwanLT/79fe477a298901ed57f3b7d4e3388ed0.js %}
We will not need it anymore, so you can suppress them from your [pom.xml](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html).
Those 3 dependencies will be replaced by just one
{% gist https://gist.github.com/ErwanLT/07d45ff54a728be4373b7f161f078275.js %}
With just this dependency we will have:

* The json generated [http://localhost:8080/v3/api-docs/](http://localhost:8080/v3/api-docs/)

* The UI page [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html)

* The bean validation

At this point, we should have some compilation problems because of some annotations due to the missing dependencies that we have replaced.
We will corrige that now.

## Step 2: changing the annotations of the endpoints

In the previous tutorial, we documented our API using a configuration class
{% gist https://gist.github.com/ErwanLT/0bf1a720652eaed3b574ebe51f7e066f.js %}
Here we have 2 choices

* declaring a new configuration class

* Using annotations in one of our [controllers](https://javarevisited.blogspot.com/2017/11/difference-between-component-service.html)

I will give you 2 equivalent example of the previous code in OpenApi way

### Configuration class
{% gist https://gist.github.com/ErwanLT/0442137964c747ed48fa43f79b203e0f.js %}
### With annotations
{% gist https://gist.github.com/ErwanLT/c2e9d37ffcd54f532c5ecd1dd8fedbce.js %}
### What it will look like in the UI

The previous example will look the same in the UI page, so it’s up to you to choose what method you want to use

![](https://cdn-images-1.medium.com/max/2000/1*cspnv6JdTib09Vhkti8ldg.png)

## Step 3: changing the annotations of the endpoints

### Swagger 2.0 annotation

Let’s take an example
{% gist https://gist.github.com/ErwanLT/0ecffe452d0f278952e2eaa3364a434d.js %}
Here is a [POST method](https://www.java67.com/2016/09/when-to-use-put-or-post-in-restful-web-services.html) documented with classique Swagger 2 annotations

* **@ApiOperation** : Describes an operation or typically a HTTP method against a specific path.

* **@ApiResponses** : A wrapper to allow a list of multiple ApiResponse objects. Here I have 2 **@ApiResponse** to describe my 200 and 500 HTTP status return code.
I can also describe what my status will return, the 200 will respond with an objet, so I added the object class to *response* field.

That will render like the following picture in the UI page

![](https://cdn-images-1.medium.com/max/5200/0*lEy9hNfq7JKeiSXM.png)

![](https://cdn-images-1.medium.com/max/5200/0*umcAcTvxyu9sBGZB.png)

Here a second example with this time a GET method
{% gist https://gist.github.com/ErwanLT/1e0e27fe7ffe0df6bca5b6ed8048f46a.js %}
Here in addition of the previous annotations, I have added the documentation of the method parameter using **@ApiParam**.

![](https://cdn-images-1.medium.com/max/5556/1*XGoQfsjUPQN9mroeA368pA.png)

With the new dependency, the annotation described are no longer the same.
So let’s see what has changed.

### OpenAPI annotations
{% gist https://gist.github.com/ErwanLT/660b84cd73cc6c2efab97396df9723cc.js %}{% gist https://gist.github.com/ErwanLT/cb48cd685bab8e5c669d63245ac074f0.js %}
With the 2 above example who is the same method that i used previously we can now see some of the changes that was operated.

* **@ApiOperation **-> **@Operation**, the *value* field become *summary* and *notes *become *description.*

* **@ApiResponse** : the field *code* become *responseCode* and is no longer an integer but a string, also the field *message* become *description*.
The biggest change is that the response field is now an annotation. **@Content.**

* **@ApiParam** become **@Parameter**

They are other change, but since they are not used here, i recommend you to use the [openAPI documentation](https://springdoc.org/#Introduction).

## Step 4: changing the annotations of the models

### Swagger 2.0 annotation

So in Swagger 2 when i wanted to document an object, my class looked somewhere like this
{% gist https://gist.github.com/ErwanLT/46488b2f44ccbcd454c4a7d5fc1905bc.js %}
As you can see, my classe is annoted with the **@ApiModel** and it’s properties with **@ApiModelProperty.
**The **@ApiModelProperty** allow us to add definitions such as description (value), name, data type, example values, and allowed values.

### OpenAPI annotations

If you look closely at my ApiResponse with status code 200, you will see that the response is now **@Content**, and that we gave the schema field the class that will be returned like this @Schema(implementation = MyClass.class).
With that annotation, OpenApi know which class to load, so i don’t have to annotate my class with an **@ApiModel** like annotation, but I still can document my property.
{% gist https://gist.github.com/ErwanLT/03a9898b300a61d42e81ee7bcbdc3f0a.js %}
So, what I have done here ?
Like previously, my fields are documented, but I have used 2 differentes method for some validation (size).

I can use the bean validation annotation, or I can use the property of the Schema annotation, the result will be the same.

![](https://cdn-images-1.medium.com/max/2112/1*YhvQOL3wccWxluJrjwLjZQ.png)

The position property don’t exist anymore, the fields are in the same order as the class.

Thanks for your reading time, as previously, the code used in this tutorial is findable in [this Github repository](https://github.com/ErwanLT/HumanCloningFacilities), branch toOpenApi.