Abstract
半年ほど前に OpenAPI Generator を使う機会があったので、思い出しながらまとめておきます。
まず、OpenAPIとは、RESTful APIを記述するためのフォーマットのことです。
スキーマ駆動開発で使われたりします。
スキーマ駆動開発は、「先にスキーマを定義し、フロントエンドの開発着手を早めることで、全体的な開発速度向上の効果が期待できる開発手法」のことです。
OpenAPI Generator
はそのスキーマを定義して、ソースを自動生成するための一つのツールです。
OpenAPI
と比較されるものとして他には、gRPC
や GraphQL
などがあります。それらについては、エンジニアHubの記事で比較されています。
備考:スキーマ駆動開発(SDD)は、2015年7月に掲載された論文Schema-Driven Development of Semantic MediaWikisが元ネタで、現在では、DeNAやFreeeなどが採用しているようです。
また、Open API と Swagger は基本的には同じなのですが、別のプロジェクトとして開発されています。
経緯がややこしいのですが、SpeakerDeckの平静を保ち、コードを生成せよ 〜 OpenAPI Generator誕生の背景と軌跡 〜で、詳しく説明されているので、気になる方はそちらを参考にしてください。
前置きが長くなってしまいましたが、本記事では、Spring Frameworkを使う前提で、Open API ver3.0
について触れます。
備考:OpenAPI Generator で使える言語やフレームワークは、公式サイトに記載されています。
1. What you need to use the Open API
必要なものは以下です。
- APIを定義するYAMLファイル
- YAMLファイルからソースコード/ドキュメントを生成するための設定ファイル
1.1. YAML FILE
YAMLファイルに定義するものは、主に以下の3つです。
- メタ情報
- エンドポイント
- コンポーネント
- schemas
- responses
- parameters
- examples
- requestBodies
- headers
- links
- callbacks
- securitySchemes
userstore.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
openapi: 3.0.0
info:
title: Sample API
description: A short description of API.
termsOfService: http://example.com/terms/
contact:
name: API support
url: http://www.example.com/support
email: support@example.com
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.0
servers:
- url: http://localhost:8080/v1
description: Development server
paths:
/users:
get:
tags:
- users
summary: Get all users.
description: Returns an array of User model
parameters: []
responses:
'200':
description: A JSON array of User model
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
example:
- id: 1
name: John Doe
- id: 2
name: Jane Doe
post:
tags:
- users
summary: Create a new User
description: Create a new User
parameters: []
requestBody:
description: user to create
content:
application/json:
schema:
$ref: '#/components/schemas/User'
example:
id: 3
name: Richard Roe
responses:
'201':
description: CREATED
/users/{userId}:
get:
tags:
- users
summary: Get user by ID.
description: Returns a single User model
parameters:
- name: userId
in: path
description: user id
required: true
schema:
type: integer
responses:
'200':
description: A single User model
content:
application/json:
schema:
type: object
items:
$ref: '#/components/schemas/User'
example:
id: 1
name: John Doe
/products:
get:
tags:
- products
summary: Get all products.
description: Returns an array of Product model
parameters: []
responses:
'200':
description: A JSON array of Product model
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Product'
example:
- id: 1
name: Apple
price: 200
- id: 2
name: Orange
price: 150
components:
schemas:
User:
type: object
required:
- id
properties:
id:
type: integer
format: int64
name:
type: string
Product:
type: object
required:
- id
- price
properties:
id:
type: integer
format: int64
example: 1
name:
type: string
example: Laptop
price:
type: integer
example: 1200
security:
- api_key: []
tags:
- name: users
description: Access to Users
- name: products
description: Access to Products
|
1.2. Gradle Setting File
OpenAPI を Gradle で使うにあたって、Openapi-generator-gradle-plugin の公式サイトが参考になります。
また、Gradleプロパティは、以下の設定にしています。
単に、build.gradle
にある設定値を一元管理するためです。
1
2
|
openApiVersion=v1
sampleStoreService=userstore
|
1.2.1. Generate Server Side File
ConfigOptions
の設定により、生成されるソースが変更されます。
openapi-generator/spring.md にSpringの場合の全オプションについて記載されています。
また、supportingFiles
の設定により、出力されるソースを制限することができます。
備考:
後から分かったのですが、.openapi-generator-ignore
の設定により、出力対象を制限することができるようです。
参考URL : OpenAPI-Generator Customization
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
task openApiGenerateSampleServer(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
validateSpec = true
generatorName = "spring"
inputSpec = "$projectDir/specs/${sampleStoreService}.yaml"
outputDir = "$projectDir"
apiPackage = "openapi.sample.${sampleStoreService}.webapi.${openApiVersion}.api"
modelPackage = "openapi.sample.${sampleStoreService}.webapi.${openApiVersion}.model"
generateModelTests = false
generateApiTests = false
generateModelDocumentation = false
generateApiDocumentation = false
// Spring Option Doc
// https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/spring.md
configOptions = [
title : "userstore",
groupId : "openapi",
delegatePattern : "true",
dateLibrary : "java8",
hideGenerationTimestamp: "true",
serializableModel : "true",
returnSuccessCode : "true"
]
systemProperties = [
apis : "",
models : "",
supportingFiles: "ApiUtil.java"
]
}
|
1.2.2. Generate Client Side File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
task openApiGenerateSampleClient(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
validateSpec = true
generatorName = "java"
inputSpec = "$projectDir/specs/${sampleStoreService}.yaml"
outputDir = "$projectDir"
apiPackage = "openapi.sample.${sampleStoreService}.clientapi.${openApiVersion}.api"
modelPackage = "openapi.sample.${sampleStoreService}.clientapi.${openApiVersion}.model"
generateModelTests = false
generateApiTests = false
generateModelDocumentation = false
generateApiDocumentation = false
// Java Option Doc
// https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/java.md
configOptions = [
title : "userstore",
groupId : "openapi",
delegatePattern : "true",
dateLibrary : "java8",
hideGenerationTimestamp: "true",
serializableModel : "true",
library : "resttemplate"
]
systemProperties = [
apis : "",
models : "",
supportingFiles: "ApiClient.java,Authentication.java,HttpBasicAuth.java,HttpBearerAuth.java,ApiKeyAuth.java,RFC3339DateFormat.java"
]
}
|
1.2.3. Generate API Documents
1
2
3
4
5
6
7
8
9
10
11
12
13
|
task openApiGenerateHtml(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
validateSpec = true
generatorName = "html2"
inputSpec = "$projectDir/specs/${sampleStoreService}.yaml"
outputDir = "$projectDir/doc"
invokerPackage = "openapi.sample.${sampleStoreService}.clientapi.${openApiVersion}"
// HTML2 Option Doc
// https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/html2.md
// 以下のイシューが対応されるまで、Schemaは空で出力されてしまいます。
// https://github.com/OpenAPITools/openapi-generator/issues/3788
}
|
2. Note
Open APIで、ドキュメントを生成する際は、個人的には公式の方法よりもReDocがおすすめです。
リンクを張っておきますが、こんな感じで見れて、めっちゃいい感じです。
公式の方法で、html
として出力すると、以下の画像ようになります。
(少し殺風景な感じです。)
3. Refference