技術書を読んでブログで定期的(できたら毎週💦)アウトプットすることを目標にしております🏃
今回は第2弾として、Webを支える技術を読んで学んだことや、本をきっかけに自分で調べたことをまとめてみました💡
実務未経験者の学習内容アウトプットですので、おかしな点等あればご指摘いただけますと幸いです🙇♂️
学んだこと
第1部 Web概論
第3章 REST Webのアーキテクチャスタイル
リソースとは
リソースとは「Web上に存在する、名前を持ったありとあらゆる情報」のこと。
RESTでは、すべてのコンテンツや情報は「リソース」として表現される。
リソースは一意のURI(Uniform Resource Identifier)によって識別される。
例えば、ウェブサイト上の特定のページ、画像、文書などがリソースになる。
リソースの表現
サーバとクライアントの間でやり取りするデータのことを「リソースの表現」と呼ぶ。
リソースは一つ以上の表現形式を持ち得る。例えば、JSONやXML形式でデータを表現することができきる。
クライアントはリクエストを通じて特定の表現形式を要求することができる。
リソースの状態
リソースの状態とは、そのリソースが特定の時点で持っているデータや情報のこと。
ウェブサーバー上のリソースは、時間の経過や外部からの操作によって状態が変化することがある。
RESTとは
RESTとは、次の6つのスタイルを組み合わせたアーキテクチャスタイルのことである
クライアント/サーバ
システムをクライアントとサーバの二つの部分に分離することにより、クライアントとサーバは独立して開発されることができ、クライアントはユーザーインターフェイスに、サーバはデータストレージやデータ処理に焦点を当てることができる。
ステートレスサーバ
サーバがクライアントの状態(セッション)情報を保持しないことを意味する。
各リクエストは自己完結型(リクエストが実行されるために必要なすべての情報を含んでいる)であり、サーバはリクエスト間で情報を保持する必要がないため、システムの拡張性が向上し、サーバの負荷が軽減される。
キャッシュ
リソースの鮮度に基づいて、一度取得したリソースをクライアント側で再利用する方式。
上記により、同じリクエストに対するサーバの負荷を軽減し、パフォーマンスが向上する。
統一インターフェース
URIで指定したリソースに対する操作を、統一した限定的なインターフェースで行うアーキテクチャスタイルのこと。
システム全体の単純化が進み、異なるクライアントやサーバ間の相互運用性が向上する。
階層化システム
システムを複数のレイヤーに分けることを意味し、各レイヤーは独立して機能する。
システムの複雑さを管理しやすくなり、セキュリティとスケーラビリティが向上する。
例:サーバとクライアント間に設置するロードバランサやプロキシ
コードオンデマンド
サーバからクライアントにコード(JavaScriptなど)を送り、クライアント側で実行する能力。
クライアントの機能を動的に拡張することができる利点がある一方で、ネットワーク通信におけるプロトコルの可視性が低下するという欠点がある。
第2部 URI
第5章 URIの設計
- URIを変更しないように設計することが重要
- どうしてもURIを変更したいときは、できる限りリダイレクトするようにする
- シンプルなURLは覚えるのが簡単なので、ユーザービリティが高まる
URIの設計指針
- URIにプログラミング言語依存の拡張子を使用しない(.phpなど)
- URIに実装依存のパス名を利用しない
- URIにプログラミング言語のメソッド名を利用しない
- URIにセッションIDを含めない
- URIはそのリソースを表現する名詞にする
URIの設計のテクニック
コンテントネゴシエーション(Content Negotiation)
ウェブ通信においてクライアント(例えばウェブブラウザ)とサーバー間で最適なリソースのバージョン(例えば言語、フォーマット、エンコーディングなど)を選択するプロセスである。
このプロセスは、クライアントが求めるリソースの特定のバージョンに対して、サーバーがどのように応答するかを決定する際に使用される。
コンテントネゴシエーションのプロセスは以下の通り。
- クライアントの要求
クライアントはHTTPリクエストをサーバーに送信する。このリクエストには、クライアントが好むリソースの種類を示すヘッダー(例えばAccept-Language
やAccept
など)が含まれている。これらのヘッダーは、クライアントが望む言語、ファイルフォーマット、エンコーディングなどをサーバーに伝える。 - サーバーの評価
サーバーはクライアントからのリクエストを受け取り、提供可能なリソースの中から最も適切なものを選択する。たとえば、サーバーはウェブページの複数の言語バージョンを持っている場合、クライアントが要求する言語に合わせて適切なバージョンを選択する。 - レスポンスの送信
サーバーは選択したリソースをクライアントに送り返す。このとき、レスポンスにはクライアントの要求に対応したコンテンツタイプや言語などの情報が含まれている。
第3部 HTTP
第6章 HTTPの基本
TCP/IPとは
TCP/IP(Transmission Control Protocol/Internet Protocol)は、インターネット上でデータを送受信するための基本的な通信プロトコル
IP
このプロトコルは、各デバイスに一意のアドレス(IPアドレス)を割り当て、インターネット上でデバイスを識別するための役割を果たす。
IPでは、データの基本的な通信単位を「パケット」と呼び、指定したIPアドレスを送り先として、パケット単位でデータをやり取りして通信する。
IPでは、自分のネットワークインターフェースでデータを送ることだけを保証し、送り出したデータが、多数のルータを経由して最終的な送り先まで届くかどうかは保証しない。
TCP
IPが保証しなかったデータの転送を保証する役割を果たす。
TCPで接続したコネクションで転送するデータが、どの¥アプリケーショにn亘かを決定するのがポート番号。
リクエストとレスポンス
クライアントで行われていること
- リクエストメッセージの構築
- リクエストメッセージの送信
- レスポンスが返るまでの待機
- レスポンスメッセージの受信
- レスポンスメッセージの解析
- クライアントの目的を達成するために必要な処理
サーバで行われていること
- リクエストの待機
- リクエストメッセージの受信
- リクエストメッセージの解析
- 適切なアプリケーションプログラムへの処理の委譲
- アプリケーションプログラムから結果を取得
- レスポンスメッセージの構築
- レスポンスメッセージの送信
HTTPのステートレス性
ステートレスとは「サーバがクライアントのアプリケーション状態(セッション状態)を保存しない」制約のこと。
セッションとは、システムにログインしてからログアウトするまでの一連の操作のこと。
ステートフルの利点と欠点
ステートフルサーバでは、サーバは常にクライアントのセッション状態を覚えているため、クライアントとサーバ間のやりとりは簡潔になるが、サーバがセッション状態を継続的に記憶し続ける必要があるため、メモリやデータベースリソースをより多く消費する。
1つのサーバが同時に対応できるクライアントの数には上限があり、サーバを増やすと複数のサーバ間でセッション状態を同期する必要があるため、クライアントの数が増えていくとスケールアウトさせにくくなる。
ステートレスの利点と欠点
ステートレスサーバでは、各クライアントが自分のセッション状態を伝え、サーバが覚える必要がないため、スケーラブル(拡張しやすい)。サーバは過去の状態を追跡する必要がないため、リソースを効率的に使用可能。
ただ、サーバをステートレスにするためには、クライアントは毎回必要な情報を全て送信しなければならず、送信するデータ量が多くなり、パフォーマンスに影響を与える。
第7章 HTTPメソッド
他のメソッドでは対応できない処理を行うPOST
通常、ウェブ上での検索はGETリクエストを使って行われ、検索キーワードはURLのクエリパラメータとして含まれるが、検索キーワードが非常に長い場合や機密性が高いデータを扱う場合など、GETリクエストの制限(URL長の制限やセキュリティ上の理由など)によりPOSTリクエストを使用することが適切な場合がある。
- GETリクエストの問題点
GETリクエストでは、URLの長さに制限があるため、長い検索キーワードや多数のパラメータを含むクエリを送信することが難しい。また、GETリクエストでは送信されるデータがURLに露出するため、機密性が要求される情報には適していない。 - POSTリクエストの使用
POSTリクエストを使用すると、検索キーワードやその他のパラメータはリクエストのボディに含められ、URLには表示されない。これにより、より長い検索キーワードを安全に送信でき、URLの長さに関する制限を回避できる。
べき等性
同じリクエストを複数回行ってもサーバー上のリソースの状態が変わらないことを意味する。
つまり、一度以上同じ操作を行っても結果が変わらない性質のこと。
べき等なHTTPメソッド
- GET
リソースを取得するだけで、サーバーの状態を変更しない。 - PUT
指定したリソースを特定の状態に更新する。同じリクエストを繰り返しても、リソースは同じ状態に保たれる。 - DELETE
指定したリソースを削除する。最初のリクエストでリソースが削除され、以降のリクエストは何も変更しない。
非べき等なHTTPメソッド
- POST
リソースを作成または変更する。同じPOSTリクエストを繰り返すと、新しいリソースが毎回作成されるか、異なる結果が生じることがある。
安全性
安全性は、HTTPメソッドがサーバーのリソースの状態を変更しないことを意味する。
安全なメソッドは、リソースを読み取るだけで、それを変更または削除しない。
安全なHTTPメソッド
- GET
サーバーのリソースの状態を変更せずに、情報を取得するために使用される。 - HEAD
GETと同様で、ボディを持たず、ヘッダー情報のみを返す。
安全でないHTTPメソッド
- POST, PUT, DELETE
これらのメソッドはサーバー上のリソースを作成、更新、削除するため、安全ではない。
第8章 ステータスコード
ステータスコードの分類と意味
- 1xx: 処理中
一時的なレスポンスを表し、クライアントに通信が継続していることを示す。
「ちょっと待ってね、まだ処理しているよ」とサーバーが言っている状態。 - 2xx: 成功
リクエストが成功したことを示す。 - 3xx: リダイレクト
他のリソースへのリダイレクトを示す。クライアントはこのステータスコードを受け取ったとき、レスポンスメッセージのLocationヘッダを見て新しいリソースへ接続する。 - 4xx: クライアントエラー
クライアントからのリクエストに問題があることを示す。
エラーを解消しない限り正常な結果が得られないので、同じリクエストをそのまま再送信することはできない。 - 5xx: サーバーエラー
これらはサーバー側に問題があることを示し、リクエストは正しくても処理できないことを意味する。
サーバ側の原因が解決すれば、同一のリクエストを再送信して正常な結果が得られる可能性がある。
よく使われるステータスコード
201 Created
リクエストが成功し、新しいリソースが作成されたことを示す。
POSTの場合、新しく作成したリソースのURIがレスポンスのLocationヘッダに絶対URIとして入る。
PUTの場合、クライアントが新しいリソースのURIを知っているため、Locationヘッダは入らない。
301 Moved Permanently
リクエストされたリソースが永続的に新しいURLに移動されたことを示す。
古いURIを残しつつ、新しいURIに移行する際にこのステータスコードを用いる。
303 See Other
リクエストされたリソースは別のURIで見つけることができ、リダイレクトされるべきであることを示す。
ブラウザからPOSTでリソースを操作した結果をGETで取得する時に用いる。
400 Bad Request
リクエストが不正または誤っていることを示す。
他に適切なクライアントエラーを示すステータスコードがない場合にも用いる。
401 Unauthorized
認証が必要であることを示す。
レスポンスのWWW-Authenticateヘッダで、クライアントに対して認証方式を伝える。
404 Not Found
リクエストされたリソースがサーバー上に見つからないことを示す。
レスポンスボディにはその理由が入る。
500 Internal Server Error
サーバー内部でエラーが発生し、リクエストを処理できないことを示します。
レスポンスボディには異常の理由が入る。
503 Service Unavailable
サーバが一時的にリクエストを処理できない状態であることを示す。
通常、一時的な過負荷またはメンテナンスによるもの。
第9章 HTTPヘッダ
認証
Basic認証
ユーザー名とパスワードをコロン(:)で結合し、Base64でエンコードしてHTTPヘッダに含める。
エンコードされた情報はデコードが容易なため、セキュリティは低い。通常はHTTPSと組み合わせて使用する。
Digest認証
Basic認証よりセキュリティが強化された方式。
ユーザー名とパスワード、サーバーからのnonce(一度きりの値)を使ってハッシュ化されたレスポンスを生成し、これをHTTPヘッダに含めます。
パスワードは直接送信されず、ハッシュ化された形でやり取りされるため、Basic認証より安全。
キャッシュ
HTTPのキャッシュ用ヘッダは、Webページや画像などのリソースがどのようにキャッシュ(一時保存)されるかを制御するために使用される。
これらのヘッダは、Webサイトのパフォーマンスを改善し、サーバーの負荷を減らすのに役立つ。
Cache-Control
リソースがどのように、そしてどれくらいの期間キャッシュされるべきかを指定する。
(例)
Cache-Control: no-cache は、リソースをキャッシュしてはならないことを示す。
Cache-Control: max-age=3600 は、リソースが3600秒(1時間)キャッシュされることを意味する。
Expires
リソースが古くなる(もうキャッシュされない)時刻を指定する。
例: Expires: Wed, 21 Oct 2023 07:28:00 GMT は、指定された日時にリソースが期限切れになることを示す。
ETag
リソースの特定のバージョンを識別するための一意の識別子。
ブラウザがキャッシュされたリソースが最新であるかどうかを確認するために使用される。
Last-Modified
リソースが最後に変更された日時を示す。
ブラウザがリソースのキャッシュを新鮮かどうかを判断するために使用される。
第5部 Webサービスの設計
第16章 書き込み可能なWebサービスの設計
排他制御
排他制御は、複数のプロセスが同時に同じリソース(例えば、データベースのレコードやファイル)にアクセスする際に、データの競合や破損を防ぐための方法。
簡単に言うと、一度に一つのプロセスだけがリソースを使用できるようにする仕組み。
例えば、二人のユーザーが同じデータベースのレコードを同時に更新しようとしたとき、排他制御がなければ、一人の変更がもう一人の変更に上書きされる可能性がある。
これを防ぐために、排他制御は一人のユーザーが変更を終えるまで、他のユーザーがそのレコードにアクセスできないようにする。
楽観的ロック
楽観的ロックは、「競合が発生することは稀である」という前提に基づいている。
このアプローチでは、データの更新時に競合が発生することはほとんどないと見なされ、そのためロックを事前にかけない。代わりに、以下のようなプロセスが採用される。
- バージョン管理
データにはバージョン番号やタイムスタンプが付与される。 - 更新時のチェック
データを更新する際、保存されたバージョン番号と現在のバージョン番号が比較される。
もし番号が異なれば、他のプロセスによってデータが変更されたことを意味する。 - 競合発生時の対応
競合が検出された場合、エラーが発生したり、ユーザーに通知されたりする。
必要に応じて再試行することもできる。
悲観的ロック
悲観的ロックは、「競合が頻繁に発生する」という前提に基づいている。
このアプローチでは、データの更新前に明示的にロックをかけることで、他のプロセスが同時にそのデータにアクセスするのを防ぐ。プロセスは以下のように進行する。
- ロックの設定
特定のデータやリソースに対してロックをかける。
このロックは、データの読み取りまたは更新を試みる他のトランザクションをブロックする。 - データの操作
ロックがかかっている間、データを安全に読み取りまたは更新できる。 - ロックの解放
操作が完了したら、ロックを解放し、他のプロセスがアクセスできるようにする。
本の内容を理解するために自分で調べたこと
Ajax
Ajax(Asynchronous JavaScript and XML)は、ウェブアプリケーションの開発技術の一つで、ウェブページの一部だけを更新することで、ページ全体を再読み込みすることなく、ユーザーインターフェイスの速度とパフォーマンスを向上させることが可能。
Ajaxを使用することで、ウェブページはサーバーと非同期にデータを交換し、ページの一部分だけを更新できる。例えば、ソーシャルメディアサイトで新しい投稿を読み込む、オンラインフォームで郵便番号に基づいて住所を自動入力する場合に効果的。
Ajaxの主なコンポーネントは以下の通り。
- JavaScriptとDOM(Document Object Model)
ウェブページ上の要素を操作し、ユーザーのアクションに応じて動的に内容を更新する。 - XMLHttpRequestオブジェクト
JavaScriptを使用してサーバーと非同期にデータをやり取りするための主要な技術。これにより、ページの再読み込みなしにサーバーからデータを取得し、ページの特定の部分だけを更新できる。 - CSSとXHTML
ユーザーインターフェイスのスタイルと構造を定義する。 - XML
データ交換のフォーマットとして用いられることが多いが、現在ではJSON(JavaScript Object Notation)の方がより一般的に使用されている。
ステータスコードの400と422の違い
HTTPステータスコードの400と422は、両方ともクライアント側のエラーを示しているが、その原因と使われ方に違いがある。
400 Bad Request
このステータスコードは、リクエスト自体が不正であることを示す。
具体的には、リクエストが曖昧、誤解を招く、あるいは完全ではない場合に使用される。
クライアントが無効なリクエストフォーマットを送信した場合、例えばJSONが正しくフォーマットされていない、または必須のフィールドが欠けている場合などに使用される。
422 Unprocessable Entity
本では解説されていなかったが、Rails7のコントローラーでよく記載していたので、再度調べてみた💡
このステータスコードは、リクエスト自体は正しいが、内容が処理できないことを示す。
例えば、ユーザー登録フォームで年齢に「-5歳」と入力された場合などに使用される。
SOAPとRESTの違い
SOAP(Simple Object Access Protocol)はアプリケーション間の通信用プロトコルで、主にXML形式のメッセージをHTTPなどを介して送信することに重点を置いている。
下記の特徴がある。
- SOAPはW3Cによって標準化されており、厳格な規則に基づいている。
- セキュリティ、トランザクション管理、エラーハンドリングなどの機能が組み込まれており堅牢。
- メッセージはXML形式で、比較的大きく重い。
RESTとの主な違いは下記の通り。
- 内容
SOAPはプロトコル、RESTはアーキテクチャスタイル。 - データフォーマット
SOAPはXMLを使用するのに対し、RESTはJSON, XML, HTMLなど多様なフォーマットに対応している。 - セキュリティと機能
SOAPはセキュリティ、トランザクション管理、エラーハンドリングなどの点で優れているが、RESTはこれらの機能をシンプルに提供する。 - 軽量性とパフォーマンス
RESTはSOAPに比べて軽量であり、通常パフォーマンスが高い。
JSONPとCORS
JSONP(JSON with Padding)
- 同一オリジンポリシーの制限(ウェブページが異なるオリジン(ドメイン、プロトコル、ポート)のサーバーからデータを直接取得することを基本的に禁じること)を回避するために考案された手法。
<script>
タグを使用してデータを取得する。<script>
タグは同一オリジンポリシーの影響を受けない。サーバーはJSONデータをJavaScript関数の呼び出しとして返す。- セキュリティリスクがあり、GETリクエストのみ可能。エラーハンドリングが困難。
CORS(Cross-Origin Resource Sharing)
- 安全なクロスドメインリクエスト(不特定多数のドメインに属するサーバへのリクエスト)を可能にするための標準的な手法。
- HTTPヘッダを使用して、サーバがクロスオリジンのリクエストを許可するかどうかをブラウザに伝えることにより、ブラウザは安全に異なるオリジンからのデータを取得できるようになる。
- 全てのHTTPメソッド(GET、POST、PUTなど)に対応し、安全で柔軟な通信が可能。
JSONPとCORSの違い
- セキュリティ
CORSはJSONPよりも安全。CORSではサーバが許可したオリジンのみがデータにアクセスでき、不正なスクリプトの実行リスクが低減される。 - HTTPメソッド
JSONPはGETリクエストのみに限られるが、CORSはGET、POST、PUTなどすべてのHTTPメソッドに対応している。 - 制御と柔軟性
CORSはサーバーサイドでの設定により、どのオリジンからのアクセスを許可するかを細かく制御できるが、JSONPではこのような制御はない。 - エラーハンドリング
CORSはエラーのハンドリングが容易だが、JSONPではエラーレスポンスの処理が困難。
JSONPは依然として機能するが、セキュリティと柔軟性の面でCORSに劣るため、新しいプロジェクトでは推奨されない。
CORSが、クロスオリジンアクセス制御の現在のグローバルウェブ標準である。
感想
- 分かりやすい説明と豊富な図解のお陰で、複雑な概念でも理解しやすいと感じた💡
- 特に「REST」について、プログラミング学習中に遭遇する度にググって様々なサイトの解説を読んでもよくわからずそのまま放置の繰り返しだったが、この書籍のお陰で何となくイメージが掴めた気がする🙌
- フレームワーク(Rails)の勉強ばかりして、これまでWebの基礎を疎かにしていた自分にはとても勉強になる内容ばかりだった✏️
- Atom関連の章は、今後触る機会なければ流し読み程度でいいかも🤔
- 現在あまり使われていない(推奨されていない)技術の話がところどころ含まれているかも??と感じた(AtomとかJSONPの部分とか。今はたぶんCORS推奨?)
コメント