REST APIについてのお勉強2（&WEB API）


# 参考

WebAPI学習ソースまとめ - Qiita
http://qiita.com/y-some/items/7e05540d7563f7c1c101

よさげな学習リソース

## API設計する際に念頭におくとよさそう

5分で絶対に分かるAPI設計の考え方とポイント (1/6) - ＠IT
http://www.atmarkit.co.jp/ait/articles/1511/19/news022.html

<!-- 
> API設計を学ぶべき背景と前提知識、外部APIと内部API、エンドポイント、レスポンスデータの設計やHTTPリクエストを送る際のポイントについて解説する。おまけでAPIドキュメント作成ツール4選も。
> ...
> 次ページからAPI設計の考え方とポイントを5分（1ページ約1000文字）で解説していきます。
> ...
>内部APIに関しては、利用するユーザーが社内などコミュニケーションを取れる人の場合が多く、かつドメイン知識もあるので、細かい作り込みが可能です。
> ...
> 外部APIであれば、「どのデータを公開するのか」を選定し、「ユーザーに何を取得させたいのか、または編集させたいのか」を決めることから始めます。
> また内部APIでも、「どのサービスに使わせる予定なのか」「どうしてDBアクセスではなく、APIにするのか」という理由を明確にすることから始めます。APIを介するということは、DB操作と比較して無駄なオーバーヘッドがあることを忘れてはいけません。
> ...
> 誰に向けたAPIかを決めることは、APIのリクエストとレスポンスをどう設計するかを決めることです。
> APIとはプログラミング用のインターフェースなので、結局UI（ユーザーインターフェース）を考えることと一緒です。
> ...
> 最適な解を見つけるには、各企業が公開しているAPIを見たり、実際に自分が使ってみたりして使いやすいものを取り入れる、というアプローチが最短距離かと思います。
> ...
> さまざまなAPIを触ってみて得た経験を基に、使いやすい設計というものを筆者なりにまとめてみました。APIの設計という意味では、HTTPリクエストにおける「エンドポイントの設計」と「レスポンスの設計」があります。
> ...
> 完全にRESTfulな設計にこだわり過ぎるのも考えものです。やはりAPIを設計していくと、どうしてもサービス固有のデータ形態があるので、RESTfulにはできないケースが出てきます。そういうときは、ユーザーが最も使いやすいと思うものを提供できるよう、臨機応変に考えを張り巡らせてユーザーファーストなAPIを作っていただければと思います。
> ...
> あるAPIがあったときに、別のAPIのリクエスト方法も推測できるように設計するべきです。
> ...
> PATCHに関しては対応していないフレームワークもあり得るので、採用は慎重になった方がいいかもしれません。
> ...
> レスポンスはなるべく分かりやすく設計する必要があります。一番重要なのは統一性です。
> ...
> ヘッダーを確認するよりもボディの内容を確認する方が楽なので、ボディに入れて返してあげるのが、ユーザーフレンドリーでしょう。
> ...
> ヘッダーに情報を入れるケースは多いと思います。例えば、認証のための情報を例に挙げると、「X-Auth」「X-Token」などが使われます。自分で定義したものに関しては、「X-」を付けるのが一般的です。
> ...
> API Blueprint：APIドキュメントのための拡張Markdown記法
Apiary：API Blueprintを利用したWebサービス。ドキュメント生成と同時にモックサーバーも生成される
Swagger：APIの統合的フレームワーク。Swaggerの記述方法は、YAMLとJSONのどちらでも可能。ドキュメント生成エディターのWebサーバーまでOSSとして提供されている。先日、これをベースに「Open API Initiative」が発足した
Apigee：APIドキュメントの作成とAPIマネジメントを提供するWebサービス。Swaggerから作成でき、モックサーバーの作成も可能
-->

* API設計をする際の前提知識
* APIの設計に入る前に考えておくべきこと
	* なぜAPIを作ろうとしているのか
	* 誰に向けたAPIか
	* APIの設計方法
* エンドポイントの設計
	* 人間が見て何をするか理解しやすいURI
	* ルールが統一されているURI
* HTTPリクエストを送る際のポイント
* レスポンスデータの設計
* APIドキュメント作成ツール4選

RESTful APIにおける基本的な考え方 | NTT Communications Developer Portal
https://developer.ntt.com/ja/blog/92ae9651-557e-482c-8f53-59cbce049c02

> さらにURLのクエリーを使って操作内容の細かな指定を行います。例えば一覧画面の場合、取得件数を指定するのが一般的です。その際、 GET /users/1/posts/limit/100 とはしません。 GET /users/1/posts?limit=100 とします。

件数指定ならパラメータだけど、、
込み入ったことをするならリソースとしてpathを変えてもいいという認識。。

APIStudy #5参加レポート | NTT Communications Developer Portal
https://developer.ntt.com/ja/blog/9b84f95b-31dc-42c2-950b-5c2f6c9d340c

実際的なことが書いてあって参考になる。

> APIキーが紙で届く
コピペできない…
自動発行ではない
今すぐ使いたいのに自分が使いたいときに使えない
パスが直感的ではない
/stationは駅の情報を返すんだろうと予想できる。/course/station、/course/passStationでは何が返ってくるのか分からない。
パラメータが多すぎる
仕様を読むのが大変。
JSONが使いづらい
紐付いているindexの番号が0はじまりじゃなく1はじまりになっている。配列の最初なのにindexが1。
さらに戻り値が配列だったり、オブジェクトの場合も。例えば結果が複数の場合は配列になり、1つの場合はオブジェクトになるといった具合。

普通に起こりそうなので気を付けたい。。

* バージョン管理できるようにしておく
* セキュリティの実装はシンプルにしておく
* パスの統一性をもたせる
* ドメインの区切りを管理側と分けると共通で使え無い部分が出てこ無いか気をつける
* 高負荷な処理についてはバッファリングなどもあり得る

# 事例

HerokuのAPIデザイン | SOTA
http://deeeet.com/writing/2014/06/02/heroku-api-design/

> それぞれのリソースにデフォルトでid要素を提供すること．特別な理由がない限りUUIDを使うこと

guid - UUID format: 8-4-4-4-12 - Why? - Stack Overflow
http://stackoverflow.com/questions/10687505/uuid-format-8-4-4-4-12-why

UUIDはtime, version, clock_seq_hi, clock_seq_lo, nodeとな。
いまいち必然性がわかって無い。

# JSON-PATCH

PUT vs PATCH vs JSON-PATCH | Phil Sturgeon
https://philsturgeon.uk/api/2016/05/03/put-vs-patch-vs-json-patch/

プロパティがラジオボタンのように二者択一している場合には、
連動しているのでJSON-PATCHがいいのではということか。ちがうかも。
トランザクションが必要にならないか、不整合が出ないかなど気をつける。

JSON PointerとJSON Patch - Qiita
http://qiita.com/taknuki/items/76d2fda912443b6854a4

> やりすぎるとSOAPみたいになるかも。

使い方。
ロールバックについても書いてた。

# REST CLIENT

REST APIを使った開発のお供に。クライアントソフトウェアまとめ | NTT Communications Developer Portal
https://developer.ntt.com/ja/blog/REST-API%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E9%96%8B%E7%99%BA%E3%81%AE%E3%81%8A%E4%BE%9B%E3%81%AB%E3%80%82%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%BE%E3%81%A8%E3%82%81

とりあえず入れとく。

# サービスの連結

Webサービス同士を簡単に連結させるタスクランナーサービスまとめ | NTT Communications Developer Portal
https://developer.ntt.com/ja/blog/2472716b-91d0-462f-aeb4-d0201799dfc2

APIでやらなくてもいい範囲ならこのへんでいけるのかも。

# フレームワーク

REST APIを構築するのに使えるフレームワークまとめ | NTT Communications Developer Portal
https://developer.ntt.com/ja/blog/0ff7d83e-d2d4-4c11-8990-4dd4896d2300

サーバーレスじゃなさそうだけどフレームワークまとめ。
「サーバーレスなAPIについて検討メモ」で調べた以外の選択肢。

# レスポンスのフォーマット

規模や特性に応じて選定を。APIのレスポンスフォーマットまとめ | NTT Communications Developer Portal
https://developer.ntt.com/ja/blog/d9c821fd-b9f2-4736-9258-b6c584412286

google/protobufがきになる。。

Protocol Buffersを試してみる - CLOVER
http://d.hatena.ne.jp/Kazuhira/20140223/1393144924

ProtocolBuffersについて調べてみた - Qiita
http://qiita.com/aiueo4u/items/54dc5dd8c4772253634c

バイナリ型のjsonみたいな。ある程度読めるけど、読めなかったりもする。
jsからも読めるのかしら。
良さそうだけど保留かな。。

Protocol Buffers はもう古い？ 爆速プロトコル SBE とメッセージングライブラリ Aeron！ - Qiita
http://qiita.com/rkyymmt@github/items/86b4aac0774b0cc164b3

気になるけど保留。

Protocol Buffers 入門
https://www.slideshare.net/yuichi110/protocol-buffers-61413028?from_action=save

> 26. Protobuf が JSON/XML に勝る点 • reader/writer の処理を自分で書かなくて良い • 読み書きの処理速度に優れる • コード変更時のバグが少ない • データ量が減るため通信が高速化 • 第三者への難読化 26
> 27. Protobuf が JSON/XML に劣る点 • protocol buffers のインストールが必要 • ブラウザなどを通した「外部」からの利用には向いていない • サービスの「内部」での利用がメイン • 小さいデータのやりとりには手間がかかりすぎる 27

わかりやすい。

# 私的なメソッドとURLの場合分けのまとめ

ひとまずで、場合わけしてみただけなので多分に怪しい。
下層のアクションと、リソースのプロパティの区別が意識しづらいかも。

* シンプルなリソース操作

	/action/:id

* 似てるけど、一つの操作とするには、意味が違ったり、複雑な処理（テンプレート処理して取得）の場合

	/action/:id/sub

* 横断的だったり全く違う処理の場合

	/action2
	/action3/:id
	/:id
		ヘッダーでメソッドを指定

* オプション指定（件数制限、フィルターなど）の場合

	/action/:id?param=hoge
	/action/:id/sub?param=hoge

* 隠蔽データのPOSTなんだけど、宛先はログなどで明確にしたい場合

	/action/:id
	/action/:id/sub
	ヘッダーなどでデータ

* セキュリティ的にURLからリソース番号を隠蔽したい場合

	/action
	ヘッダーなどでid

* パラメータが長くなる時などに、URLをシンプルに保つ必要がある場合

	/action
	/action/id
	ヘッダーなどでパラメータ

* 部分置換

	/action
		PATCH (or PUT)

* 部分置換だけどプロパティが明確化できて個別でアクセスさせる場合

	/action/:id/property1
		PUT

* 部分置換だけどプロパティが明確化できて個別でアクセスさせたいけど整合性を取る必要がある場合というか、、
	* 対象がJSONの場合？わかってない。
	* たぶん、PATCHという挙動はあくまで意味的で挙動はPUTと同じだから、JSONの一部を更新する場合には別のメソッドでやろうよということかしら。

	/action/:id
		JSON-PATCH

# PUT(PATCH)を使ったほうがいいのか

いまさらながら、、リクエスト側で、既存のリソースなのかどうかをしっていないと区別でき無いけどどうなんだろう。
DBへのクエリーとかだと下記だけど、トランザクションやロックは手間がかかりそうだし。

* selectして確認
* トランザクションをはる
* insertかupdate
* レスポンスで確認
* トラザンザクションを必要に応じて巻き戻す

プレゼンテーション側に近づくと遅延が大きくなる気がする。
POSTしたらその先が判断したほうがいいこともないのかどうか。
低レベルAPIはPATCHとかPUTを明確にして、高レベルAPIはPOSTでいいよ。とか。

ロックの問題ももっとシミュレーションしたほうがいいのかしら。
APIの先にDBがあるならばあまり気にしなくて大丈夫なのかどうなのか。

GETとPOSTだけでRESTfulなサービスを作れるか
https://www.infoq.com/jp/news/2010/06/get-post-alone-restful

> RESTfulなサービスのインターフェイスがいつもCRUDと一致するとは限らない
> ...
> HTTPで状態を変更する処理のすべてにPUTを利用する必要はありません。RESTもそのようにすべきだと規定しているわけではありません。

REST における PUT メソッドと POST メソッドの違い - 星一の日記
http://d.hatena.ne.jp/hajimehoshi/20090710/1247161012

> リソースの新規作成における PUT と POST の違いについてまとめます。 PUT はクライアントが作成したいリソースの URI が明確である場合に用います。一方 POST は新しく作成されるリソースの URI がサーバーによって決まる場合に用います。 SQL に例えるならば、PUT は ID を伴う INSERT 文ですが、 POST は ID を伴わない INSERT 文です

うーん、オートクリメントとかじゃなくて呼び出し元でユニークなシーケンス的なものを振るならPUTはいい気がする。
日時とIPを何らかの変換してからハッシュとかの番号をつけてPUT的なイメージ。
そうであれば、よく言うPUTが更新の役割というのは厳密ではないのかな。

Webの成功理由は制約 ８つしかないHTTPメソッド
http://kaihooo.com/http-method/

> POSTとPUTの使い分け
> POSTとPUTの使い分けは、URIの決定権がクライアントとサーバのどちらにあるかがポイントである。つまり、URIの決定権がクライアントにあるものがPUT（Wikipediaなど）、サーバにあるものがPOST（Twitterなど）である。特別な理由がない限りは、リソースの作成はPOSTで行いURIもサーバ側で決定する、という設計が望ましい。
> ...
> POSTは安全でもべき等でもないため、複数回送ることに慎重でなければならない。例えば、ショッピングサイトなどで二重注文をしてしまうことがある。
> ...
> GETに隠された安全性、PUTとDELETEのべき等性、そしていざとなったらなんでもできるPOST。HTTPはそれぞれのメソッドにあった性質と拡張性を備えた、優れたプロトコルと言える。

PUTやDELTEが冪等ではなくなる場合について書いてあったりおもしろい。

RESTful API の設計のキホン - SSSSLIDE
http://sssslide.com/speakerdeck.com/cside_/restful-api-falseshe-ji-falsekihon

> RPCは良く言えば自由、悪く言えばバラバラなものができあがりがち
> したがって多くの場合でRESTを選択するべき
> ネットを見ると「 REST は考えることが多くてだるいよねー、RPC 最高！」という意
見が散見されるが、そう発言する人のほとんどは、REST の「制約によるコンセン
サス」というメリットを無視しているので注意
> ...
> 単一のリソースのことを一般的にエントリリソース と呼ぶ
> 複数リソースのことを一般的にコレクションリソース と呼ぶ
> ...
> 排他制御処理を行ないたい場合
レスポンスヘッダの Etag や Last-Modified を用いた
Conditional Request (条件付きリクエスト)
という手法を用いるのが一般的。（⇒ RFC7232 ）
いわゆる楽観ロック相当の排他制御をすることが可能
話すと長いのでここでの説明は割愛
「 Conditional Request 」「条件付きリクエスト」等で
各自ぐぐってくだださい。
> ...
> オーバーロード POST という手法を用いて
HTTP Method をオーバーライドする方法がある

いろいろ広く記載されていて参考になる。

ja/08.3.md · 7649d66a1c9cc26b808f266683a7a4d180512bba · roth / build-web-application-with-golang · GitLab
https://gitlab.com/roth1002/build-web-application-with-golang/blob/7649d66a1c9cc26b808f266683a7a4d180512bba/ja/08.3.md

Restfulについての概念的な説明が詳しい。
Restの実装の３段階のレベル分けの記述があり参考になる。
getのみ、オーバーロードPOST、５段活用のrest

# CRUDとRESTが違う、動詞はURLに含め無いという話について

POSTがCreateでPUTがupdate、、でいけるときもあるけど基本は違う。
この辺の考え方からも、設計の考え方に分岐が起きたりしているのか。。