1 Overview
In this article we consider example of using code generation by OpenAPI specification. This is the API-First approach to building service. Code generator will be used for generating code in java-spring application. Full source code of example project on GitHub
2 Specification
Let's start with writing simple OpenAPI specifications. Here we use an example with 'Get' and 'Create' operations for some Clients.
openapi: 3.0.3
info:
title: client-api
description: 'Client API'
version: 1.0.0
paths:
/client:
get:
parameters:
- name: id
in: query
required: true
schema:
type: string
format: uuid
description: Client id
responses:
200:
description: Success response with client
content:
application/json:
schema:
$ref: "#/components/schemas/ClientResponse"
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
required: true
responses:
200:
description: Success response with client
content:
application/json:
schema:
$ref: "#/components/schemas/ClientResponse"
components:
schemas:
ClientResponse:
type: object
properties:
success:
type: boolean
description: Operation success flag
message:
type: string
description: Error description
client:
$ref: "#/components/schemas/Client"
required:
- success
- message
- object
Client:
type: object
description: Client data
properties:
id:
type: string
format: uuid
description: Client unique id
name:
type: string
description: Client name
maximum: 32
minimum: 2
dateOfBirth:
type: string
format: date
createdAt:
type: string
description: Date of client registration
format: date-time
banned:
type: boolean
description: Ban flag
countAccounts:
type: integer
description: Count of client accounts
minimum: 0
serviceRate:
type: string
description: Service rate
enum:
- "FREE"
- "STANDARD"
- "VIP"
3 Setup dependencies
Let's setup OpenAPI generator maven plugin
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.2.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/specs/client-api.yaml</inputSpec>
<generatorName>spring</generatorName>
<apiPackage>dev.toliyansky.openapi.api</apiPackage>
<modelPackage>dev.toliyansky.openapi.model</modelPackage>
</configuration>
</execution>
</executions>
</plugin>
4 Code examples
After run mvn clean install
generated classes will be placed into target directory.
To implement the HTTP route we should create a class that extends generated controller.
@RestController
@RequestMapping("/api")
public class ClientController extends ClientApiController {
private final RandomExceptionService randomExceptionService;
public ClientController(NativeWebRequest request, RandomExceptionService randomExceptionService) {
super(request);
this.randomExceptionService = randomExceptionService;
}
@Override
public ResponseEntity<ClientResponse> clientGet(UUID id) {
var clientResponse = new ClientResponse();
try {
var client = new Client(); // Stub. But in real project get client from service level.
clientResponse.setSuccess(true);
clientResponse.setClient(client);
randomExceptionService.generateException50percentChance();
return ResponseEntity.ok(clientResponse);
} catch (Exception e) {
e.printStackTrace();
clientResponse.setSuccess(false);
clientResponse.setMessage(e.getMessage());
clientResponse.setClient(null);
return ResponseEntity.internalServerError().body(clientResponse);
}
}
@Override
public ResponseEntity<ClientResponse> clientPost(Client client) {
var clientResponse = new ClientResponse();
try {
// Do some actions with client in service level.
client.id(UUID.randomUUID());
clientResponse.setSuccess(true);
clientResponse.setClient(client);
randomExceptionService.generateException50percentChance();
return ResponseEntity.ok(clientResponse);
} catch (Exception e) {
e.printStackTrace();
clientResponse.setSuccess(false);
clientResponse.setMessage(e.getMessage());
clientResponse.setClient(null);
return ResponseEntity.internalServerError().body(clientResponse);
}
}
}
Now we can test it with HTTP request
### Create client
POST http://localhost:8080/api/client
Content-Type: application/json
------
HTTP/1.1 200
Content-Type: application/json
{
"success": true,
"message": null,
"client": {
"id": "6796a90a-314a-4667-a7cc-dfbe592b27e5",
"name": "Anatoliy",
"dateOfBirth": "2020-01-01",
"createdAt": "2020-01-01T00:00:00Z",
"banned": false,
"countAccounts": 3,
"serviceRate": "VIP"
}
}
### Get client by id
GET http://localhost:8080/api/client?id=6796a90a-314a-4667-a7cc-dfbe592b27e5
Accept: application/json
------
HTTP/1.1 200
Content-Type: application/json
{
"success": true,
"message": null,
"client": {
"id": "6796a90a-314a-4667-a7cc-dfbe592b27e5",
"name": "Anatoliy",
"dateOfBirth": "2020-01-01",
"createdAt": "2020-01-01T00:00:00Z",
"banned": false,
"countAccounts": 3,
"serviceRate": "VIP"
}
}
5 Conclusion
In this article, we saw how to generate a java-spring service with an API-First approach with OpenAPI YAML specification and OpenAPI generator maven plugin.
Full source code of example project on GitHub
Top comments (0)