読書要点「Webを支える技術」：第5部「Webサービスの設計」

# 第15章 読み取り専用のWebサービス設計

Webサービスの設計のためには、個々の技術の知識だけでなく全体の設計についても知識や技術が必要位なる。
リソースの設計に必要なURIによる名前付け、リソース表現の選択、ハイパーリンクの活用について考えていく。

### リソース設計とは何か

Webサービス設計と言ってもその作業は広範に渡る。
その中でもリソース設計について扱う。

リソース設計とは、クライアントとサーバ間のインターフェースの設計、つまりWebサービスの外部設計である。
リソースの種類、表現、操作方法、リンク関係を構築していくことになる。

リソースの設計の際は、人に向けたWebサービスとプログラムに向けたWeb APIを切り分けないことが大切である。
同じ技術、アーキテクチャを使っている両者を分けて考える必要はない。

### リソース指向アーキテクチャのアプローチ

リソース設計には一般的な設計手法が確立されているわけではない。
指針として存在しているのはリソース思考アーキテクチャで推奨されている設計アプローチである。
オブジェクト指向プログラミングにおけるオブジェクトのようにリソースを捉え、設計することを勧めている。

- Webサービスで提供するデータを特定する
- データをリソースに分ける
- リソースにURIで名前を付ける
- クライアントに提供するリソースの表現を設計する
- リンクとフォームを利用してリソース同士を結びつける
- イベントの標準的なコースを検討する
- エラーについて検討する

それぞれについて順に検討を進める。

### Webサービスで提供するデータを特定する

そのサービスで提供するデータを理解、特定して置かなければリソースの設計はできないため、最初に行うべき作業である。

### データをリソースに分ける

特定したデータをリソースに分割する作業で、難しい工程である。
サービスを使う側が実際に触れるもの、取得するものをリソースにするべきであり、機能そのものではなく、結果をリソースとして捉える必要がある。

### リソースにURIで名前を付ける

リソースに適したURIで名前を付けていく作業である。
扱いやすさ、わかりやすさを意識した上で、一般的な慣習に基づいた普遍的な名前を付けていくのがよい。

### クライアントに提供するリソースの表現を設計する

Web上における代表的な表現形式は以下のようなものとなる。

| 分類 | 表現形式 |
|:--|:--|
|  XML表現 |   XHTML|
|   |  Atom |
|   |  独自XML |
|  軽量フォーマット表現 |JSON/JSONP   |
|   |   YAML|
|   |   CSV|
|   マルチメディア表現|画像   |
|   |   映像|
|   |  マルチページ画像 |

どのようなサービスであり、なにを提供したいのかに応じてどの表現を用いるのかを選択していくことになる。
XML表現はプログラミング言語が処理系を用意しており、最適な表現として選択されやすい。
実装する上では、既存フォーマットを参照しつつ実装し、足りないところを自分で補っていくことが大切。

### リンクとフォームを利用してリソース同士を結びつける

それぞれのリソースをリンクやフォームを利用して結びつけていく。
サービスをちゃんと提供できるようなリンク設計が必要である。
わかりやすく使いやすい設計を目指して漏れなく作業することが大切。

### イベントの標準的なコースを検討する

提供者側が、利用者がどのようなフローでサービスを利用するのかを検討する。

### エラーについて検討する

正常な動作の確認や想定外の入力、操作を見越してエラーを検討する作業である。
セキュリティ上の問題もあるが、利用者がサービスの要求を確認し、問題なく利用できるようにする上でも重要である。

# 第16章 書き込み可能なWebサービスの設計

### 書き込み可能なWebサービスの難しさ

読み取り専用のサービスと比べ、書き込み可能なWebサービスには考えなければならないことがたくさんある。
複数のユーザからの同時の書き込み、エラー時の予期しない動作の予防、複数のリソースの更新などが挙げられる。

複雑になり、指針を見失ってしまいがだが、以下のことに留意しておくと良い。

- なるべくシンプルに保つ。
- 困ったらリソースに戻って考える。
- 本当に必要ならPOSTでなんでもできる。

### 書き込み可能な郵便番号サービスの設計

以下の機能の設計について述べていく。

- リソースのCRUD操作
- バッチ処理
- トランザクション
- 排他制御

### リソースの作成

ファクトリリソースという、リソースを作成するためのリソースにPOSTする方法と、PUTで直接作成する方法がある。
一般的にはPOSTを使うことが一般的であるが、PUTを使う場合もある。
PUTのメリットとして、

- POSTの実装が不要となりサーバ側の実装が簡単。
- クライアントが作成と更新を区別する必要がなく、クライアント側の実装が簡単。

といった点がある。
一方で、PUTを用いることによるデメリットもある。

- クライアントがURIの構造を把握しておく必要がある。
- リクエストの見た目から作成と更新を区別できない。

###リソースの更新

PUTで更新を行う。
後述のバッチ処理はPOSTで行う。

リソース全体を記述するバルクアップデートと変更点のみを記述するパーシャルアップデートがある。

### リソースの削除

DELETEを送ることでリソースの削除を行える。
親リソースを削除した際に子リソースも削除されるように設計しておくことが望ましい。

### バッチ処理

複数のリソースを編集したいときに、サーバへの接続回数を減らすため、一括で編集できるような機能がバッチ処理である。
PUTだと更新対象のURIの指定が必要なため、POSTにより送信を行い、サーバ側の実装で一括処理できるようにする。

### トランザクション

複数のリソースにまたがった変更をひとまとまりに扱う処理をトランザクションと呼ぶ。
例えば銀行の残高であれば、実際にお金を引き出す処理と残高を減らす処理は必ずセットで行わなければならないような処理で必要になる。

このために用いるのがトランザクションリソースである。
名前の通り、トランザクション情報を表現するリソースである。

処理の流れとしては以下のとおりである。

- POSTによるトランザクションリソースの作成
- トランザクションリソースへの処理対象の追加
- トランザクションの実行
- トランザクションリソースの削除

### 排他制御

複数のクライアントによるリソースの操作時に競合が起きないようにする処理を排他制御と呼ぶ。
排他制御の方法は悲観的ロックと楽観的ロックの大きく2つにわけられる。

##### 悲観的ロック

HTTPによる悲観的ロックの実装には独自のロックリソースを用意するか、WebDAVのLOCK/UNLOCKメソッドを使う。
編集者に固有のトークンを付与し、その情報を持つもの以外は編集できないようにする。
編集がおわったらそのトークンによるロックを解除する。

##### 楽観的ロック

悲観的ロックに対し、常に同じ文書を複数人が編集することはないという経験則から、競合が起きた場合のみ制御を行う仕組みを楽観的ロックという。
編集の状態を示すタグを用いた条件付きPUTや条件付きDELETEを用いることで簡単に実装できる。

競合が発生した場合の対応として配下のものが考えられる。

- 競合を起こしたユーザに確認し、更新・削除を行う。
- 競合を起こしたデータを、別リソースに保存する。
- 競合を起こしたユーザに変更点を伝え、マージを促す。

# 第17章 リソースの設計

リソース指向アーキテクチャの設計アプローチによるWebサービスの設計は流れがわかりやすく問題がなければ採用したい手法だが、実際に進めていく上で落とし穴に引っかかることがある。
それは**Webサービスで提供されるデータを特定**し、**データをリソースに分ける**方法が確立していない点である。

このリソースの設計にあたる作業を補助するために、既存の設計手法で得られている成果物を参考にするやり方がある。

ここでは、

- 関係モデルのER図
- オブジェクト指向モデルのクラス図
- 情報アーキテクチャ

を取り上げている。
必ずしもWebサービスに必要なリソースすべてに直結するとは限らないが、リンクの関係性や必要なリソースの洗い出しに役立てることができる。