In this post I will show you how to start developing a new API using the API-First approach, Spring Boot and the OpenApi initiative. But first of all, let’s clarify some basic concepts.
There are basically two approaches when developing APIs: Code First and API First.
Code First
The code first approach consists in starting to program your REST controllers and increase the functionality of the API right after you have received the requirements. Afterwards, you can add some Swagger annotations in your code in order to generate the API documentation.
In a nutshell: First code, then documentation.
API First
The API first (or design first) approach focuses on the API’s design before starting to write the code. The resulting code will be the output of our design, which means that the first thing we need to do is to write the API specification (OpenApi). That is, we will design how our API will look like and how it should work before starting to write any line of the code. To do that we can use some online tools like the Swagger Editor.
I personally prefer the second one (API first) for several reasons:
- The API specification is the single point of truth. We will be able to generate the REST interfaces as well as the API documentation from a single file which contains all the information of our API
- Contract first. Once we have designed our API, we know how it should behave and we can start writing contracts. Contracts are basically request-response pairs which define the behaviour of the different endpoints and we can use them to generate REST-Assured tests as well as Wiremock stubs without writting any line of code!. Actually I think I will write a new post about this topic 😉
- Improves maintenance. We can have an overall overview of our API in a human-readable format
Let’s start!
In this tutorial, we will design a very basic API which will allow us to manage a list of tasks for different projects. For a first version, the API needs to meet the following requirements:
- Create a new project
- Get the list of created projects
- Get the info of a specific project
- Delete a project
- Get the tasks of a project
- Get a specific task of a project
- Update the information of a task (title, description…)
- Delete a task
Write the OpenApi specification
Once we have the requirements, we can start with the technical design. We need to translate the above functionalities into different endpoints using the OpenApi specification. As result, we need to obtain something like this.
Generate the API using the OpenApi generator plugin
After designing our OpenApi specification, we can take advantage of the OpenApi generator plugin to generate the API itself. The result will be a list of interfaces and controllers which correspond to our specification.
First of all, there are some parameters we need to provide to configure the plugin, like the location of our OpenApi specification, the output path where the generator should place the code, or even what kind of generator we want to use, in our case «spring» but there are much more supported. If you need more information, please visit their documentation.
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/spec/openapi-spec.yml</inputSpec>
<generatorName>spring</generatorName>
<apiPackage>${project-base-package}</apiPackage>
<modelPackage>${project-base-package}.model</modelPackage>
<invokerPackage>${project-base-package}.swagger</invokerPackage>
<skipValidateSpec>false</skipValidateSpec>
<strictSpec>true</strictSpec>
<importMappings>Problem=org.zalando.problem.Problem</importMappings>
<ignoreFileOverride>${project.basedir}/.openapi-generator-ignore</ignoreFileOverride>
<generateApiDocumentation>false</generateApiDocumentation>
<generateModelDocumentation>true</generateModelDocumentation>
<configOptions>
<delegatePattern>true</delegatePattern>
<configPackage>${project-base-package}.swagger</configPackage>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
Afterwards, we need to execute the command «mvn compile» and voilà!, our API will be automatically generated.At this point, we are finally able to start our application and if everything is correct, we should see the Swagger-UI displaying all the endpoints we have designed in our OpenApi specification:
Implement the endpoints
We have seen how easy it is to get a running API with just the OpenApi specification. We could now deploy the API into a dev environment and the consumers could start having an idea of how to integrate our API in their website or mobile app.
Little problem: if they call any of the endpoints, they will get a 501 – Not Implemented error message.
Now it’s our turn. The OpenApi generator has provided the whole list of interfaces with all the endpoints we have designed, and now they need to be implemented. To do that, we just need to create a new RestController and implement the generated interface. To implement the endpoints, just override the method definition and program your logic inside, for example:
@RestController
public class ProjectsApiImpl implements ProjectsApiDelegate {
@Override
public ResponseEntity<Project> getProject(Integer projectId) {
Project project = new Project();
project.setProjectId(projectId);
project.setDescription("The description of the project");
project.setTitle("My awesome project");
return new ResponseEntity<>(project, HttpStatus.OK);
}
}
If we call the endpoint now, we will get the following response:
Summary
This is it for now. What have we done?
- Understand the differences between Code First and API First
- Design an API specification using the OpenApi initiative
- Generate the API interfaces and controllers with the help of the OpenApi generator maven plugin
- Example of how to implement the endpoints to provide a valid response
Starting from this example, in the next tutorial I will show you more cool stuff you can implement in your APIs to provide a very high quality and efficiency. Stay tuned!
This project is available on my Github.