システムデザインの概念（part3: APIs）

### **クライアント-サーバーモデル**

- **クライアント**:クライアント-サーバーモデルにおいて、クライアントとは、サーバーが提供するサービスにアクセスするアプリケーションやシステムのことを指します。ウェブブラウザ、メールソフト、モバイルアプリなど、様々な形態を取ることができます。特定の情報やサービスを取得するためにリクエストを送信し、通信を開始します。

- **サーバー**:サーバーとは、ネットワーク上のクライアントやその他のサーバーにリソース、データ、サービス、機能を提供するコンピューター、デバイス、ソフトウェアのことです。クライアントからのリクエストを待ち受け、それらに応じて、ウェブページの提供、メールの処理、データベースアクセスの提供などの対応を行います。

- **入れ替わる役割**:クライアントとサーバーの役割は、状況によって入れ替わることがあります。1台のコンピューターが、クライアントとサーバーの両方の役割を同時に果たすこともあります。例えば、ウェブサイトがサードパーティからデータを要求する場合などです。P2Pネットワークもこの役割の入れ替わりを示しています。

- **発信者と着信者**:クライアントは通常「発信者」と呼ばれ、リクエストを発信します。一方サーバーは「着信者」とみなされ、サービスを提供したり、リクエストを処理したりします。

クライアント-サーバーモデルを理解することは、ネットワークやシステム設計において非常に重要です。なぜなら、このモデルがネットワーク間の通信やリソース共有の基盤となっているからです。

### **HTTPプロトコル(HyperText Transfer Protocol)**

IPとTCPの上に構築されたプロトコル。開発者として、私たちはこれをある程度制御できます。

基本的にはIPはデータパケットを送信元から宛先に転送する役割を担いますが、パケットが到着する順序は重視しません。

一方、TCPはIPの上に構築され、パケットが正しい順序で届くことを保証します。

HTTPはTCPの上に位置します。HTTPはリクエスト/レスポンスのプロトコルです。データがどのように形式化され、ネットワーク上で転送されるべきか、またサーバーとブラウザがさまざまなコマンドにどのように応答すべきかについての一連のルールです。ブラウザ経由で呼び出しを行うたびにHTTPが使用されます。

ブラウザの開発者ツールを使えば(ウェブで右クリックしてInspectそしてNetwork)、HTTP内容を確認できます。ウェブブラウザにURLを入力し、開発者ツールを開いてネットワークタブを見ると、リクエスト名、ステータスコード、リクエストタイプ、レスポンスサイズ、リクエスト完了時間などの重要な詳細が表示されます。

HTTPリクエストの解析:
- **リクエストメソッド**: 提供されたリソースに対して実行する想定された操作を示します。例えばGET(リソースの取得)、POST(リソースが処理するデータの送信)、PUT(更新)、DELETE(削除)などのメソッドを使用できます。
- **リクエストURL/URI**: リクエストを送信先のURLを指定します。ここでは/resultsというパスも含まれ、?search_query=somethingでパラメータを指定しています。これは検索ボックスに入力した内容を反映しています。
- **ヘッダー**: ヘッダーはリクエストに関する追加情報を提供します。これらはレスポンスヘッダーまたはリクエストヘッダーです。
- **HTTPリクエストヘッダー**: リクエストに関する必須情報を提供し、メソッド、スキーム、そして何より重要なのはクライアントが受け入れられるデータタイプを示します。下の図のように、私たちのブラウザはtext/HTMLを受け入れます。
- **HTTPレスポンスヘッダー**: レスポンスまたはサーバーに関する追加情報を提供します。クッキーの設定(Set-Cookie)、キャッシュ動作の指定(Cache-Control)、コンテンツタイプの指定(Content-Type)なども行います。
- **ボディ**: すべてのHTTPリクエストにボディが含まれるわけではありません。例えばGETリクエストにはボディがありません。データを送信するのではなく、データを取得しているためです。POSTやPUTのようなリクエストの場合、ボディにはサーバーに送信するデータ(ペイロード)が含まれています。

### **SSL/TLSとHTTPS**

- SSL/TLS: SSL(Secure Sockets Layer)とTLS(Transport Layer Security)は、ネットワーク上で安全な通信を行うためのプロトコルです。TLSはデータの暗号化により、通信の安全性を確保します。私たちはシステム設計にあまり重要ではないので、高次レベルでのみ議論しますが、ネットワーク通信の保護において重要な役割を果たします。

- HTTPS: HTTPSは、HTTPとTLSの組み合わせで、データを安全に転送するために使用されます。HTTPそのものは中間者攻撃を受けやすいため、HTTPSはSSL/TLSを用いてデータの安全性と完全性を守り、このような攻撃を防ぎます。

- SSLとTLS: SSLとTLSは頻繁に交互に使用されますが、SSLは技術的には古い用語で、TLSに置き換えられたことに注意が必要です。TLSはSSLの後継であり、より安全で強力です。

- 最も重要なプロトコルは: 総じて開発者にとって最も役立つのはHTTPSプロトコルです。HTTPSはデータの安全な転送を保証し、ユーザープライバシーとデータの完全性を守るのに不可欠です。

### WebSocket： **アプリケーションレベルプロトコル**

HTTPやWebSocket、FTP、SMTP、SSHなどのアプリケーション層プロトコルがありますが、WebRTCを除いてTCPを使用します。WebRTCはUDPを使用します。

HTTPの汎用性と利点は先に述べましたが、リアルタイムチャットアプリなど即時通信が必要なシーナリオでは、HTTPの一方向リクエスト-レスポンスモデルは効率が低く、リアルタイム性を維持するためにポーリングを頻繁に行う必要があり、パフォーマンスオーバーヘッドが大きくなる問題があります。

そこで**WebSocket**が登場しました。WebSocketは双方向通信をサポートするプロトコルで、クライアントとサーバー間のリアルタイムデータ転送を実現できます。リアルタイムチャット、ライブ配信アプリなどのシーナリオに適しています。HTTPに比べ、WebSocketはより効率的で即時性が高く、リアルタイム通信のニーズを満たすことができます。

**WebSocketの接続確立**プロセスには、クライアントからのWebSocketハンドシェイクリクエストの送信やサーバーからのハンドシェイク応答などのステップが含まれます。WebSocketではデータ転送が双方向でリアルタイムに行われます。一度WebSocket接続が確立すると、クライアントとサーバーはこの接続を介して双方向通信を直接行うことができ、HTTPのようにリクエスト-レスポンスの往復を繰り返す必要がありません。つまり、クライアントとサーバーはいつでも相手にデータを送信でき、受信側はすぐにデータを受け取れるため、リアルタイムでインスタントな通信が可能になります。WebSocketのデータ転送はTCP接続に基づいていますが、接続の上位レイヤーに双方向通信を実現する抽象化を提供しています。

ポートについて: WebSocketはHTTPと同様にデフォルトでポート80を使用します。WebSocketの安全接続ではHTTPSと同様にポート443を使用します。

### APIパラダイム

APIは、クライアントとサーバー間でネットワーク経由で操作を実行する方法です。

APIは一連のルールやプロトコルで構成されており、ソフトウェアアプリケーションの構築と連携に使用されます。

APIは、プログラム(通常はソフトウェアライブラリやOSなど)が他のソフトウェアと通信するために使用すべきメソッドやデータフォーマットを定義します。

REST、GraphQL、gRPCの3つの異なるAPIパラダイムがあり、それぞれ独自の特徴を持ち、特定のシナリオで優れた性能を発揮します。

REST、GraphQL、gRPCの他にも、SOAP(Simple Object Access Protocol)やWebhookなどの形式がありますが、ここではRESTAPI見ていきましょう。

**REST**の重要な概念:

- RESTは、REpresentational State Transferアーキテクチャのデザイン原則と標準に準拠したAPIです。
- RESTは簡単なHTTPプロトコルを使って機械間通信、特にクライアントとサーバー間の通信を行います。
- RESTAPIはクライアント-サーバーアーキテクチャが必要で、クライアントとサーバーはネットワーク経由で通信する独立したエンティティです。この分離により、クライアントとサーバーの独立した開発と更新が可能になります。
- RESTAPIはステートレスで、各クライアントリクエストにはリクエストを処理するために必要な全ての情報が含まれている必要があります。サーバーは前のクライアントリクエストの状態を保持してはなりません。これにより水平方向のスケーリングが容易になります。
- 例を挙げながら、RESTAPIにおける状態の概念と、リソース取得リクエストを処理する際にクライアントが必要なデータをリクエストに含め、サーバーが前のリクエスト状態に依存しないようにする方法が説明されています。ロードバランサーのアーキテクチャについても言及されていません。複数のサーバーが存在し、ステートレスなサーバーなのでいつでもサーバーを捨てられることから、RESTAPIはこのようなアーキテクチャに適していると言えます。
- RESTAPIはJSONフォーマットのデータを受け入れるだけでなく、レスポンスデータも同じフォーマットでラップされます。JSONの名前はJavaScriptオブジェクトの構造に似ていることに由来し、キーと値のペアをサポートし、様々なレベルのネストが可能です。JSONは情報転送の優先データフォーマットとなっています。JSONではキーと値の両方がダブルクォーテーションで囲まれ、文字列型であることを示しています。
- **過剰取得**はRESTAPIの主な問題点の1つで、コンテンツをリクエストした際に、不要なコンテンツが返されたり、コンテンツが不足していたりします。これにより、ネットワークリソースが無駄になったり、期待通りのアプリケーション効果が得られなくなる可能性があります。

### まとめ

APIは最初も私全然理解してないですが、開発しながら少しづつ理解してきました。とてもとても重要な部分なので、まずは概念などを抑えておきましょう。