API設計についての学び
APIの設計の流れ
- 作りたいアプリケーションの画面と遷移を考える(画面遷移図)
- 画面ごとに必要な情報を洗い出す
- 遷移時に何の情報を取得する必要があるのかを決めて、それを取得するためにAPIの設計を考える
まずは画面と必要な情報を洗い出す事がはじめの一歩
APIエンドポイント=APIにアクセスするためのURIのこと
エンドポイントの設計
「覚えやすく、どんな機能を持つURIなのかが一目でわかる」
- 短い
- 人間が読んで理解できる
- 大文字小文字が混在しない
- 改造しやすい
- サーバー側のアーキテクチャが反映されてない
- ルールが統一されている
なるべくシンプルに、意図が伝わるような設計にする事が大切みたい
短い:不要な情報や意味の重複をなくす
悪い例:http://api.example.com/service/api/search
ホスト名(api.example.com)でapiという事がわかっているなら、パス(service/api/search)の中にapiは必要ない
serviceという名前も、抽象的すぎて、apiと類似した意味をもつため、不要
いい例:http://api.example.com/search
これで何らかの検索用apiということがわかる
人間が読んで理解できる:略すのダメ、絶対
悪い例:http://api.example.com/sv/u
service?user ?
単語を略してしまうと、設計者からすれば理解出来るかもだけど、他の人が見た時に、「こういう意味、、だよね?」と確信に至らなくなってしまう、、bad
リーダブルコードでもこういうこと書いてた気がするな〜
和製英語や間違った意味の英語は、アクセスする際のタイポに繋がる
ほかにも似たような意味だけど、よくよく考えてみたら違ってくるような単語もある
「Search」と「find」
あとは、英語力が足りずに間違った綴りをしているかもだから気を付ける
エラーメッセージ:❌「cheack outed」 ⭕️「cheacked out」
登録する:❌「regist」⭕️「register」
registerは名詞と動詞どちらも含む
英語はちゃんとやっとかないとだな
APIについてじゃないけど、名前考える時にはこういう記事を参考にしよう
大文字小文字は混在させない:小文字がmust
ホスト名は大文字と小文字の区別が無視されるらしい
ただ、pathのほうは区別されるので、混在してると、タイポを招きやすい
大文字小文字問題への対処法はいろいろある
- どのパターンでも情報を返すようにする
- NotFoundデラーを返す
既存のサービス(GuthubやTwitter)ではNot Foundが多いみたい
ルールが統一されたURI
悪い例
友達の情報の取得:http://api.example.com/friends?id=100
メッセージの投稿:http://api.example.com/friend/100/message
個々の指定方法で、クエリパラメータとパスパラメータが混在している
特定の情報を指定する場合は、パスパラメータで
フィルターやソートの場合はクエリパラメータを使うのが良さそうだったはず、、
いい例
友達の情報の取得:http://api.example.com/friends/100
メッセージの投稿:http://api.example.com/friends/100/message
これだとみやすい
HTTPメソッド
GET, POST, PUT. PATCH, DELETE
なにをするかを表すもの
メソッドとURI
URIは「対象のリソース」を表す
メソッドは「何をするか」を表す
これ大事
こうやって考えると、下記みたいな文章が日本語化できる
GET http:/api.example.com/users/1
和訳:api.example.comから、idが1のuserの情報(api.example.com/users/1)を取得(GET)する
APIのエンドポイント設計 P34~
「データの集合」と「個々のデータ」は、DBのテーブル名とレコードの関係と同じ
テーブルやレコードに対してどんな処理を行うか == HTTPメソッド
データの集合(テーブル)に対して
- GETで一覧取得
- POSTで新規作成
個々のデータ(レコード)に対して - PUT(PATCH)で更新
- DELETEで削除
基本的には、個々のデータを表すときは
「http:/api.eample.com/articles/:id」
となり、この「:id」の部分が、データの識別子(id)となる
一覧データの場合は、あまり定まっておらず、
- 「http:/api.eample.com/articles/」
- 「http:/api.eample.com/articles/list」
のように、末尾にlistをつけたりするパターンがある
ただ、articlesで複数形になっていて、一覧というのがわかるため、基本は不要
SNSをモデルに、ソーシャル関係のAPIについて考える
友達の情報(繋がり)を制御するAPI
- 友達の追加:「users/:id/friends POST」
- 友達の削除:「users/:id/friends/:id DELETE」
- 友達の一覧取得 :「users/:id/friends GET」
- 友達の検索: 「users/:id/friends?... GET」
繋がりの情報は、ここのユーザーに紐づく情報のため、:idの後に付け足していく
追加・取得に関しては、今まで通りだが、削除は一癖ある
users/:id/friends/:id DELETE
削除する場合、指定したidの友達関係を削除するが、そのidには二つの設計方法がある
- 友達のユーザーID
- 友達関係を表す固有のID
友達のユーザーIDを使うほうがいい - 「自分のid+友人のid」で一意無関係を表せる
同じテーブルのidで管理したほうが、見やすい
エンドポイント設計での注意点
- 複数形の名刺を利用する
- 利用する単語に気をつける
- スペースやエンコードを必要とする文字は使わない
- 単語を繋げる必要がある場合は - を利用する
複数形を利用する
テーブル名と同様に、データの集合を表しているため、複数形にする
複数形にする際に、単語が大きく変わるものは気を付ける
「media->medium」「mouse->mice」など
利用する単語に気をつける
直感で選ぶのではなく、広く使われているものを参考にする
ProgrammableWebを参考にする
閉鎖していたので、以下を参考に
正直参考になるかは微妙なところ...
検索とクエリパラメータ p42
一覧データの取得は以下のよう
http::api.example.com/v1/users
ただこれだと、データが増えちゃうとデータサイズが多くなっちゃう...
あとは検索とかしたいよね....
ということで登場するのがクエリパラメータ(?)