はじめに
これまでLinuxに始まり、Git、HTML/CSS、Docker、Python、SQLと学習してきました。
ここでWebフレームワーク(Django)について学習する前にもう一つ知っておくべきことがあります。
それは、アプリケーションと人とを繋ぐインターフェース、つまりAPI(Application Programming Interface)と呼ばれるものです。
身近なWebアプリケーションとして、YouTubeを思い浮かべてみましょう。
YouTubeで観たい動画を検索して再生するには、検索窓にキーワード(例えば、「Python 入門」)を入力するだけでたくさんの動画が検索結果として表示されて、観たい動画をクリックすれば再生できます。
普段何気に使用しているこの一連の流れの中で、私たちとYouTubeの橋渡しをしているのがAPIです。
APIにはいくつか種類がありますが、本記事ではWebアプリケーションで広く使われる REST APIについて学習した内容を紹介します。
そもそもRESTってなんだ?
REST APIについて学習する際に「RESTとは、なんだろうか?」という疑問が真っ先に思い浮かびます。
REST(Representational State Transferの略)とは、Webサービスを設計するためのルールとして2000年にロイ・フィールディング氏によって提唱されたものです。
つまり、Webサービスを設計するためのルールに則ったAPIのことをREST APIといいます。
RESTのルールには次の6つが挙げられます。
- クライアント/サーバー
- ステートレス
- キャッシュ制御
- 統一インターフェース
- 階層化システム
- コードオンデマンド
RESTの6つのルール
クライアント/サーバー
1つ目のルールは、「クライアントとサーバーは分離されていなければならない」ということです。
クライアントは、サーバーが提供するリソース(データやサービス)を要求し、サーバーはその要求に応じてリソースを提供します。
YouTubeを利用する場面を想像しましょう。
クライアントは私たちが使っているブラウザやスマホアプリで、サーバーはYouTubeのデータベースやストリーミングサーバーです。
例えば「Python 入門」と検索すると、クライアントはその検索ワードをYouTubeのサーバーに送ります。
サーバーは、そのリクエストに対応する動画データをクライアントに返すことで、ブラウザやアプリで表示・再生されます。
ステートレス
2つ目のルールは、「サーバーはクライアントの状態を保持しない」ということです。
クライアントの状態を保持しないということは、以前のリクエストがどうであったかは関係なく、1度きりのやり取りでリクエストとレスポンスが成り立つということになります。
例えるなら、1話完結型のドラマです。
では、仮にステートフルだった場合を想像してみましょう。
多くのユーザーが多種多様なリクエストをサーバーに投げてきます。
その一つ一つをサーバー側に保持していたらどうでしょうか?
あっという間にパンクする気がしませんか?
だから、リクエストを独立して処理するステートレスである必要があるのです。
キャッシュ制御
3つ目のルールは、「クライアント側でレスポンスをキャッシュできるようにする」ということです。
レスポンスがキャッシュ可能かどうか指定します。
クライアントはキャッシュされたデータを利用することで、サーバーへのリクエストを減らすことができます。これによりユーザー体験の向上やリソースの効率化が見込まれます。
例えば、YouTubeの動画のサムネイル画像を考えてみましょう。
サムネイル画像は変更されることが少ないため、YouTubeはその画像をクライアントのブラウザにキャッシュさせます(キャッシュ制御)。
次に同じサムネイルが必要な場合、ブラウザはキャッシュに保存されている画像を再利用します。
これにより、サーバーへのリクエストが不要となり、ページの読み込み速度が速くなります。
統一インターフェース
4つ目のルールは、「リソースにアクセスするためのインターフェースは統一されている必要がある」ということです。
このルールは、REST APIの中心的な役割を果たすと言っても過言ではありません。
統一インターフェースには、クライアントとサーバー間のやり取りをシンプルにし、互換性を高めるための4つの制約があります。
リソースの識別
リソースは一意に識別できる必要があり、これにはURI(Uniform Resource Identifier)を使用します。
URIはリソースを特定するためのアドレスであり、リソースにアクセスするための手段となります。
YouTubeでBon Joviの"It's My Life"のOfficial Music Videoを例にすると、
https://www.youtube.com/watch?v=vx2u5uUu3DEのwatch?v=vx2u5uUu3DE
でリソースが一意に識別されています。
もちろんアクセスすればお目当てのMVが再生されます。
リソースの表現を用いた操作
リソースの表現とは、JSONまたはXMLのことを指します。
クライアントは、リソースの表現を取得し、そのデータを使ってリソースを操作することができます。
サーバーは、リソースの状態をクライアントに返す際にこれらの表現を使います。
自己記述メッセージ
この「自己記述メッセージ」とは、サーバーへのリクエストやクライアントへのレスポンスに含まれるデータのことを指します。
具体的には、メッセージのヘッダーに、ボディー部分の内容がどの形式であるかを示す情報(Content-Type)が記述されています。
HATEOAS
Hypermedia As The Engine Of Application Stateの略で、レスポンスに現在の状態を踏まえて関連するハイパーリンクを含めるということを示しています。
例えば、検索結果の表示における「次ページ」のようなリンクを含めるということです(ただし、最近のREST APIでは見かけることは少なくなったようです)。
階層化システム
5つ目のルールは階層化システムで、システムが複数の階層(レイヤー)に分かれていることを指します。 各階層は独立して機能し、他の階層とのやり取りを通じてシステム全体が動作します。
このように階層化システムとすることで、システムの柔軟性とスケーラビリティが向上しますが、処理の中でオーバーヘッド(階層化したことによる負荷)が発生し、レスポンスが悪く感じるといったデメリットもあります。
コードオンデマンド
6つ目のルールは、「クライアントにコードを送信し、クライアント側で実行することができる」です。
これによって、リリース済みのクライアントに対して機能追加といった拡張や、クライアントに処理を移譲できるので、サーバーの負荷を下げることが可能になります。
その一方で、クライアント側の実行環境(SafariやChromeなど)が増えるので、評価が複雑になるというデメリットもあります。
URI設計のポイント
URIを設計するポイントはいくつかありますが、代表的なものは以下の通りです。
- 冗長なパスを含まず、短く入力しやすいものであること
- 読むだけで理解できるものであること(省略した表記を使わない)
- すべて小文字であること
- 単語はハイフン( - )で連結すること
- 単語は複数形とすること(リソースの集合であるため)
これを踏まえ、movie
をリソースとしてURIを設計してみます。
CRUD(Create / Read / Update / Delete)操作を行う場合のHTTPメソッドとURIの関係は、以下のようになります。
URI | HTTP method | 操作 |
---|---|---|
/movies/ | GET | リソースの一覧取得 |
/movies/ | POST | リソースの新規作成 |
/movies/{id} | GET | 任意のリソースの取得 |
/movies/{id} | PUT | 任意のリソースの更新(存在しない場合は新規作成) |
/movies/{id} | DELETE | 任意のリソースの削除 |
いかがだったでしょうか?
RESTは設計思想であるため、どこか抽象的で、私も含め初学者には理解しにくい部分が多いのも事実です。
ただ、現段階で100%理解できなくとも「RESTとはこんなものだったよな」といった感じを掴めるだけでもこの先の学習の役に立つと思います。
個人的には、Djangoなどのフレームワークを学習していく過程で、RESTについて疑問に思うことがあれば、また調べればいいと思っています。
なぜなら、プログラミング学習をして何か試験を受ける訳ではないのですから。
この記事がお役に立てれば幸いです。