OpenAPI仕様(旧Swagger)からAPIクライアントのSDKを生成するツールにswagger-codegenがありますが。 同様のツールとしてMicrosoftのオープンソースにautorestがあったので試してみました。
autorestは以下の言語の自動生成に対応しています。 C#, Go, Java, Node.js, TypeScript, Python, Ruby, PHP
swagger-codegenの対応言語一覧はこちら
インストール
autorestコマンドを使えるようにします。 ちなみに、Node.js 7.10以上が必要です。
npm install -g autorest
OpenAPI Specification
今回は以下のようなAPI仕様を定義したとします。
/projects:
get:
operationId: listProjects
summary: プロジェクトの一覧取得
tags:
- Project
parameters:
- name: pickup
in: query
description: ピックアップ
required: false
type: string
responses:
200:
description: プロジェクト一覧
schema:
type: array
items:
$ref: '#/definitions/project'
400:
description: 取得NG
schema:
$ref: '#/definitions/error'
Pythonクライアントの生成
autorestを呼び出してクライアントを生成します。
--python オプションでPythonクライアントになります。
詳細なオプションはこちらを参考に。
autorest --input-file=swagger.yaml --python --output-folder=autorest_client --namespace=matsu
Pythonクライアントのソース
自動生成されたクライアントのソースコードをautorestとswagger-codegenで比較してみました。
autorest版
def list_projects(self, creator=None, pickup=None, popular=None, custom_headers=None, raw=False, **operation_config):
"""プロジェクトの一覧取得"""
# Construct URL
url = '/projects'
# Construct parameters
query_parameters = {}
if pickup is not None:
query_parameters['pickup'] = self._serialize.query("pickup", pickup, 'str')
# Construct headers
header_parameters = {}
header_parameters['Content-Type'] = 'application/json; charset=utf-8'
if custom_headers:
header_parameters.update(custom_headers)
# Construct and send request
request = self._client.get(url, query_parameters)
response = self._client.send(request, header_parameters, **operation_config)
if response.status_code not in [200, 400]:
raise HttpOperationError(self._deserialize, response)
deserialized = None
if response.status_code == 200:
deserialized = self._deserialize('[Project]', response)
if response.status_code == 400:
deserialized = self._deserialize('Error', response)
if raw:
client_raw_response = ClientRawResponse(deserialized, response)
return client_raw_response
return deserialized
swagger-codegen版(比較用)
def projects_get_with_http_info(self, **kwargs):
"""プロジェクトの一覧取得"""
all_params = ['pickup']
all_params.append('callback')
all_params.append('_return_http_data_only')
all_params.append('_preload_content')
all_params.append('_request_timeout')
params = locals()
for key, val in iteritems(params['kwargs']):
if key not in all_params:
raise TypeError(
"Got an unexpected keyword argument '%s'"
" to method projects_get" % key
)
params[key] = val
del params['kwargs']
collection_formats = {}
resource_path = '/projects'.replace('{format}', 'json')
path_params = {}
query_params = {}
if 'pickup' in params:
query_params['pickup'] = params['pickup']
header_params = {}
form_params = []
local_var_files = {}
body_params = None
# HTTP header `Accept`
header_params['Accept'] = self.api_client.\
select_header_accept(['application/json'])
# Authentication setting
auth_settings = []
return self.api_client.call_api(resource_path, 'GET',
path_params,
query_params,
header_params,
body=body_params,
post_params=form_params,
files=local_var_files,
response_type='list[Project]',
auth_settings=auth_settings,
callback=params.get('callback'),
_return_http_data_only=params.get('_return_http_data_only'),
_preload_content=params.get('_preload_content', True),
_request_timeout=params.get('_request_timeout'),
collection_formats=collection_formats)
感想
まだautorest版のクライアントは使用していないのですがソースを見た感じの感想です。
- swagger-codegenのいいところ
OperationIdを書かなかった場合にPathから自動で関数名が定義されるのでIDの重複を気にしたり余計なルールを用意しなくて済む- APIと通信するクライアントを別で生成してAPIの処理に渡せるのでクライアントが使い回せて認証処理を毎回書く必要がない
- autorestのいいところ
- OpenAPI仕様で記述したエラーの場合の詰め替えを自動でやってくれるのでSDKの呼び出し元で(余計な)例外処理をしなくて済む
- 生成されたソースが読みやすい気がする
松木佑徒