😺
Android Studioで始めるOpen API入門
概要
Open APIとは、API(Application Programming Interface)の仕様を標準化された形式で記述するための仕様のこと。
- 特徴
- APIのエンドポイント、リクエスト・レスポンスの形式、認証方法などを統一的に記述
- JSON形式またはYAML形式で定義される
- RESTful APIの設計と文書化
- できること
- API仕様書の自動生成
- クライアントSDKの自動生成
- テストケースの自動生成
- APIドキュメントの自動作成
得ること
- Android StudioでOpen API定義ができるようになる
- Swagger UIで記述した内容がドキュメントとして閲覧できる
前提:RESTful APIとは
RESTとはREpresentational State Tranfer, Webサービス設計思想の一つ
4つの原則
- アドレス可能性
- 全ての情報が一意なURIで表現されること
- 統一インターフェース
- 情報の操作(取得、作成、更新、削除)は全てHTTPメソッドを利用
- HTTPメソッド(GET/POST/PUT/DELETE)
- やりとりするデータはJSON形式
- 情報の操作(取得、作成、更新、削除)は全てHTTPメソッドを利用
- ステートレス性
- サーバーがクライアントの情報を持たないように設計
- 全てのリクエストが完全に独立していてリクエスト間で影響し合わない
- サーバーがクライアントの情報を持たないように設計
- 接続性
- 情報に別の情報や状態のリンクを含めることで別の情報に接続することができる
導入
- Android Studioのインストール
- Android Studioを開きOpenAPI(Swagger) Editorというpluginを入れる
→そうすると正しいYamlファイルを開いている時に右上にShow OpenAPI Previewと表示されるようになり、そこからドキュメントを参照できるようになる
Swagger Specificationの書き方
yamlの書き方
# 文字列
name: "Taro"
# 数値
age: 30
# boolean
is_adult: true
# null
middle_name: null
nullable: true
# 配列
fruits:
- Apple
- Banana
# 階層構造
person:
name: "Taro"
address:
street: 123
city: "tokyo"
state: "1234-abcd"
# 複数行
description: |
This
is
a
pen
# リスト内のハッシュ
users:
- name: "Taro"
age: 30
- name: Hanako
age: 25
ルートオブジェクト
定義を書く上で7つのルートオブジェクトがある
- openapi
- OpenAPIのバージョン
- 必須
- OpenAPIのバージョン
- info
- API仕様書のメタデータ
- 必須
- API仕様書のメタデータ
- servers
- APIがどんな環境で提供されるか定義
- tags
- 分類するタグ
- paths
- パス
- security
- セキュリティ要件を定義
- components
- 再利用可能にするための定義
info
licenseに関してはspdxのlicense listから取得
openapi: "3.0.3"
info:
title: "Blog Site API"
description: |
# Features
- Get Blogs
- Post Blogs
version: 1.0.0
termsOfService: "https://google.com"
contact:
name: "Customer Support"
url: "https://google.com"
email: "test@gmail.com"
license:
name: "MIT License"
url: "https://spdx.org/licenses/MIT.html"
servers
servers:
- url: "http://{enviroment}.test.com/v1"
description: "環境毎のAPIサーバー"
variables:
enviroment:
enum:
- "api"
- "dev-api"
default: "api"
description: "環境を指定します(api: 本番, dev-api: 開発)"
tags
tags:
- name: blog
description: "ブログ記事に関する操作"
- name: user
description: "ユーザー情報に関する操作"
components
共通schemaを使いまわせるようにする
components:
schemas:
BlogInfo:
type: object
properties:
id:
type: integer
description: "ブログ記事のID"
title:
type: string
description: "ブログ記事のタイトル"
content:
type: string
description: "ブログ記事の本文"
author:
type: string
description: "著者"
createdAt:
type: string
format: data-time
description: "作成日"
paths
パスを定義するステータスコード毎に記述できる
ファイルを分けて$refの内容をパス名にしても良い
paths:
/blog/{blogId}:
get:
summary: "ブログの取得"
description: "指定したブログを取得する"
tags:
- blog
deprecated: false
parameters:
- name: blogId
in: path
description: "ブログID"
required: true
schema:
type: integer
example: 1234
- name: x-Request-Id
in: header
description: "リクエストID"
required: false
schema:
type: string
example: "1234-abcd"
- name: sessionId
in: cookie
description: "セッションID"
required: false
schema:
type: string
example: "1234abcd"
responses:
"200":
description: "成功時のレスポンス"
headers:
x-Total-Count:
description: "ブログ記事の総数"
schema:
type: integer
x-RateLimit-Limit:
description: "レートリミットの上限"
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/BlogInfo'
"400":
description: "無効なリクエストID"
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: "エラーメッセージ"
"500":
description: "サーバーエラー"
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: "エラーメッセージ"
/blogs:
post:
summary: "ブログ記事を登録する"
description: "新しいブログを登録します"
tags:
- "blog"
requestBody:
description: "ブログ記事の情報"
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BlogInfo'
security
componentsにsecuritySchemesを足す
以下はAPIKey認証
他にもBasic認証、JWT認証、OAuth2.0、OpenID Connectなどで記述が異なる
components:
securitySchemes:
apiKey_auth:
description: "API key autorization"
type: apiKey
in: header
name: X-Api-key
schemas:
BlogInfo:
type: object
properties:
id:
type: integer
description: "ブログ記事のID"
title:
type: string
description: "ブログ記事のタイトル"
content:
type: string
description: "ブログ記事の本文"
author:
type: string
description: "著者"
createdAt:
type: string
format: data-time
description: "作成日"
pathに追加する
security自体をルートオブジェクトにすれば全てに適用できる
その場合はいらないpathでのsecurity:[]にしてあげる
paths:
/blog/{blogId}:
get:
summary: "ブログの取得"
description: "指定したブログを取得する"
tags:
- blog
deprecated: false
parameters:
- name: blogId
in: path
description: "ブログID"
required: true
schema:
type: integer
example: 1234
- name: x-Request-Id
in: header
description: "リクエストID"
required: false
schema:
type: string
example: "1234-abcd"
- name: sessionId
in: cookie
description: "セッションID"
required: false
schema:
type: string
example: "1234abcd"
responses:
"200":
description: "成功時のレスポンス"
headers:
x-Total-Count:
description: "ブログ記事の総数"
schema:
type: integer
x-RateLimit-Limit:
description: "レートリミットの上限"
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/BlogInfo'
"400":
description: "無効なリクエストID"
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: "エラーメッセージ"
"500":
description: "サーバーエラー"
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: "エラーメッセージ"
security: []
/blogs:
post:
summary: "ブログ記事を登録する"
description: "新しいブログを登録します"
tags:
- "blog"
requestBody:
description: "ブログ記事の情報"
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BlogInfo'
security:
- apiKey_auth: []
- apiKey_auth: []これはスコープを表している
apiKey認証の場合は全権限がそのまま付与されるのでないが、他の認証の場合読み込み。書き込み権限、管理者かどうかなどここに指定する
Discussion