When working with microservices, it is common to create a contract first using the API First approach for communication and access to our services. In such cases, OpenAPI 3 with Spring Boot is a good approach, as there are libraries available that generate interfaces to facilitate implementation.
What is OpenAPI?
OpenAPI, originally known as Swagger Specification, is a human-readable and machine-readable specification that describes an interface, producer, consumer, and visualization for RESTful web services. This makes OpenAPI 3 a valuable tool for development with Spring Boot.
The current version of OpenAPI is 3, released in 2017. In this article, we will see an example of how to generate objects and controllers in a Spring Boot application based on an OpenAPI 3 definition.
Why use OpenAPI 3?
OpenAPI 3 is a widely adopted and standardized specification for designing, documenting, and implementing RESTful APIs. Here are some reasons why OpenAPI 3 is commonly used:
- API Documentation: OpenAPI 3 provides a structured and machine-readable format to describe APIs, making it easier to generate accurate and up-to-date documentation automatically. This improves API discoverability and enables developers to understand and consume APIs more efficiently.
- Contract-First Development: With OpenAPI 3, you can define the API contract first before implementing it. This approach ensures consistency between API documentation and the actual implementation, promoting better communication and collaboration between frontend and backend teams.
- Code Generation: OpenAPI 3 specifications can be used to generate server stubs and client SDKs in multiple programming languages. This speeds up the development process by providing a foundation of pre-generated code that aligns with the API contract.
- Tooling Ecosystem: OpenAPI 3 has a thriving ecosystem of tools and frameworks that support various stages of API development. This includes validation, mocking, testing, security, and performance analysis tools. Leveraging this ecosystem can streamline API development and enhance overall productivity.
- Interoperability: OpenAPI 3 promotes interoperability and allows API consumers to easily integrate with different services and platforms. Its standard format enables seamless integration with other tools and frameworks that support OpenAPI specifications.
Overall, OpenAPI 3 simplifies API development, improves collaboration, and enhances the overall quality and usability of APIs. It has become the de facto standard for API documentation and plays a crucial role in the modern API-driven development landscape.
Using OpenAPI 3 with Spring Boot
OpenAPI 3 Dependencies in the Application
We are going to add dependencies and the plugin to run our application with OpenAPI 3:
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${springfox-version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${springfox-version}</version> </dependency>
The springfox libraries mentioned above provide automated API JSON documentation for Spring-based APIs. Later, we will see how we can visualize the provided interface using swagger-ui to work with the API.
<plugin> <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>3.3.4</version> <executions> <execution> <id>spring-boot-api</id> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec> <generatorName>spring</generatorName> <output>./</output> <configOptions> <sourceFolder>src/main/java</sourceFolder> <java8>true</java8> <interfaceOnly>true</interfaceOnly> </configOptions> <modelPackage>${folder-to-generate-model}</modelPackage> <apiPackage>${folder-to-generate-controller}</apiPackage> <modelNameSuffix>Dto</modelNameSuffix> <generateApiDocumentation>false</generateApiDocumentation> <generateModelDocumentation>false</generateModelDocumentation> </configuration> </execution> </executions> </plugin>
We have to add the above plugin within the plugins section of the pom.xml file. This plugin allows us to generate DTOs and controllers from the API specification.
Adding OpenAPI 3 to Our Spring Boot Application
First, we need to configure our Spring Boot application to use OpenAPI 3. To do this, we will enable it using the @EnableSwagger2 annotation and create a configuration class to provide information about our API, such as the title, description, and location of our controllers.
@Configuration @RequiredArgsConstructor @EnableSwagger2 public class SwaggerConfig { private final BuildProperties buildProperties; @Bean public Docket docketConfig() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.refactorizando.openapi.infrastructure.rest.spring.resource")) .build().apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title(buildProperties.getName()) .version(buildProperties.getVersion()) .build(); } }
The previous class will be in charge of the OpenApi 3 configuration. As we mentioned before, we have enabled the @EnableSwagger2 annotation and created its configuration. On one hand, we create a Bean where we add information to the API (apiInfo()) and set the package where the controllers are located. Even though it says @EnableSwagger2, it is completely valid for OpenAPI 3.
Definition of API for OpenAPI 3 format
To make Spring recognize our API.yml file where we define our API, we are going to add this file inside the resources folder.
A continuación mostramos el API.yml que se va a ejecutar en el proyecto.
openapi: "3.0.0" info: description: "Bank API" version: "1.0.0" title: "Bank API" contact: email: "refactorizando.web@gmail.com" license: name: "Apache 2.0" url: "http://www.apache.org/licenses/LICENSE-2.0.html" servers: - url: http://localhost:8000/ description: "local host" paths: /users: get: tags: - "user" summary: "Find a collection of users" operationId: "getUsers" responses: 200: description: "Retrieve users" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/User" 400: description: "BadRequest" content: application/json: schema: type: "object" $ref: "#/components/schemas/Error" 500: description: "Internal server error" content: application/json: schema: type: "object" $ref: "#/components/schemas/Error" 503: description: "Service unavailable" content: application/json: schema: type: "object" $ref: "#/components/schemas/Error" components: schemas: User: type: "object" required: - "id" properties: id: type: "integer" format: "int64" name: type: "string" example: "Francisco Martín" address: type: "string" example: "Avendia de la zarzuela" phone: type: "string" example: "+00 6656545" postalCode: type: "string" example: "28007" Error: type: "object" properties: code: type: "integer" format: "32" message: type: "string" description: type: "string"
The basic example shows how to create a Spring Boot controller from an OpenAPI specification. After define the API.yaml, we will proceed to package or install Maven in our project.
After generate our project:
- We will see how in the folder defined in apiPackage, the controller will be generated
- In the folder defined in modelPackage, the DTOs will be generated
Don’t forget to add in the .openapi-generator-ignore file those files that you don’t want to be modified by the OpenAPI plugin; for example, add pom.xml or Readme.md.
To see the dependencies and see the code, you can click here.
Conclusion
In this article, we have seen how Spring Boot can help us create controllers, DTOs, and the necessary documentation from an API developed with OpenAPI 3.
If you need more information, you can leave us a comment or send an email to refactorizando.web@gmail.com You can also contact us through our social media channels on Facebook or twitter and we will be happy to assist you!!