Spring을 사용한 OpenAPI 생성

1. 개요



이 기사에서는 OpenAPI 사양으로 코드 생성을 사용하는 예를 고려합니다. 이것이 서비스 구축에 대한 API-First 접근 방식입니다. Code generator은 java-spring 애플리케이션에서 코드를 생성하는 데 사용됩니다. 예제 프로젝트의 전체 소스 코드GitHub

2 사양



간단한 OpenAPI 사양 작성부터 시작하겠습니다. 여기서는 일부 클라이언트에 대한 'Get' 및 'Create' 작업의 예를 사용합니다.

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 설정 종속성



설정하자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 코드 예시



실행 후mvn clean install 생성된 클래스가 대상 디렉토리에 배치됩니다.



HTTP 경로를 구현하려면 생성된 컨트롤러를 확장하는 클래스를 만들어야 합니다.

@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);
        }
    }
}



이제 HTTP 요청으로 테스트할 수 있습니다.

### Get client by id
GET http://localhost:8080/api/client?id=00c4c92b-09d5-460e-a938-83d00238c6e9
Accept: application/json
------
HTTP/1.1 200 
Content-Type: application/json
{
  "success": true,
  "message": null,
  "client": {
    "id": null,
    "name": null,
    "dateOfBirth": null,
    "createdAt": null,
    "banned": null,
    "countAccounts": null,
    "serviceRate": null
  }
}

### 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"
  }
}


5. 결론



이 기사에서는 OpenAPI YAML 사양 및 OpenAPI 생성기 maven 플러그인을 사용하여 API 우선 접근 방식으로 java-spring 서비스를 생성하는 방법을 살펴보았습니다.

예제 프로젝트의 전체 소스 코드GitHub

좋은 웹페이지 즐겨찾기