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)