じぶん対策

日々学んだことをアウトプットして備忘録にしています。

「Webを支える技術」を読んで

はじめに

個人的に技術書を読む機会が最近多くなりつつあるので、その内容をまとめるとともに感じたことやわからないことなどをまとめていきたいと思います。 できるだけ丸写しではなく要点を絞ることと個人の所見を入れたいと思っています。

Webを支える技術とは

https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042

技術評論社から出版された、Webサービスの実践的な設計をテーマに書かれた技術書です。

読もうと思ったきっかけ

組み込み系からWeb系に転職した当初、Webの基本さえ全くわからない状態でした。
基礎的な知識をざっくり学びたいと考えた際に評判の良かったこの本の購入を決めました。

所感

内容のまとめの前に所感を書いておきます。

Webという業界を何も知らない状態でこの本を読んで得られたことは非常に大きかったかなと思います。
勉強することが多い業界ですが、手始めにこの本を手にして良かったと感じています。

Web業界のチュートリアルといっても過言ではないくらい必須の知識が丁寧に解説されている印象を受けました。
仕様の解説部分が多く、そのあたりは最新の情報ではなくなる可能性はあるなと感じましたが、どういうものか全く知らない状態から読むには最適な本ではあると思います。
仕様に関しては公式ドキュメントを都度参照する点を意識すれば有効に活用できる良書だと感じました。

一度読み切ってから復習を兼ねてこの記事をまとめましたが、第五部の理解度がまだまだだなと感じています。
設計経験を重ねてもう一度読み直した際に自分の意見を持って再度記事にできればと思います。

こういう類の本をまとめる際に自分の意見を入れる余地がないと感じて経験不足を実感します。。。

内容まとめ

第一部 Web概論

そもそもWebとは何か、どのような場面で使われているのかについての説明が中心となっています。

Webを支える基本的技術

  • HTTP(Hypertext Transfer Protocol)
  • URI(Uniform Resource Identifier)
  • HTML(HyperText Markup Language)

ざっくりとした内容としてはHTTP,URI,HTMLなどのハイパーメディアフォーマットについての解説があり、最後にそれらの技術を用いたWebAPIの設計例が紹介されています。

Webの歴史

どのようにWebが生まれ、標準化されていったのかについて歴史的な観点から説明されています。 生まれた時からWebが存在しているような世代の自分にとって、Web以前のシステムに関して知る機会というのはなかなかなく、またどうしてWebが残ったのかという観点からも言及されている点が良かったです。

  • Web以前のインターネット
    • 1969年にARPAANETという米国内の大学や研究機関の間を接続したネットワークが構築された。
  • Web以前のハイパーメディア

    • Memex...1945年に米国の研究者Vannevar Bushが発表したMemexという情報検索システムについてのシステムについての論文。実在するシステムではなく構想だが、リンクをたどって表示するなど現在のWebを予感させるもの。
    • Xanadu(ザナドゥ)...Memex構想に影響を受けたTed Nelsonという研究者が「ハイパーテキスト」「ハイパーメディア」という言葉を考案した。理想的なハイパーメディアXanaduを困難したが、高機能ゆえの複雑さから頓挫し、失敗に終わった。
    • HyperCard...Web以前に成功を収めたハイパーメディア。Bill Atkinsonが1987年に開発した。スタンドアロンWebサービスで、ネットワークを通じてデータをやり取りする機能はなかったが、成功を収め、たくさんのゲームやアプリケーションが開発された。
  • Web以前の分散システム

ここでもWeb以前のインターネットと同様さまざまな分散システムが登場します。具体的な内容については割愛させていただくので書籍を確認していただくとして、旧来の分散システムの問題点について言及されていたのでまとめたいと思います。

  • Web以前の分散システムの問題点

    • 性能劣化の問題 ネットワークを介しての関数呼び出しは通常の何倍も時間がかかる。
    • データ型変換の問題  プログラミング言語ごとにサポートするデータ型が異なるため、複数の言語が混在する環境ではデータ型の変換時に問題が発生する。
    • インタフェースバージョンアップ時の互換性の問題 機能追加に伴ってサーバのインターフェースを更新した場合、古いクライアントに対しての下位互換性を保てない。
    • 負荷分散の問題 一般にRPC(Remote Peocedure Call)ベースのシステムでは、クライアントのアプリケーション状態を保持する必要があり、多数のサーバで負荷を分散することが難しくなる。
  • Webの誕生

1990年、Tim Berners-Leeという研究者がWebの提案書を書きました。この年のクリスマス休暇に最初のバージョンのブラウザとサーバを完成させました。当時は企業や大学の研究者が利用していましたが、彼らは無償で公開されたサーバやブラウザをどんどん試用し、コンテンツを公開し始めます。 Mosaicというブラウザの登場によって爆発的な普及を果たします。

現在利用されている最も標準的なアーキテクチャといっても過言ではないRESTがどのように誕生したのかについても説明されています。

  • RESTの誕生

    カルフォルニア大学アーバイン校の大学院生だったRoy Fieldingによって2000年、「REST」と名付けられた博士論文が提出されます。

RESTについては以前記事を書いたのでよければ参考にしてください。

https://taisei-miyaji.hatenadiary.com/entry/2022/04/26/090757

RESTについての解説やSOAPとWS-*というアーキテクチャの解説やRESTとの対立についての解説もありますがここでは割愛します。

第二部 URI

URIとは

Uniform Resource Identifierの略。

URIの仕様

RFC3986に定義されています。

URIの構成パーツ http://blog.example.jp/entries/1を例とすると - URIスキーム : http - ホスト名 : blog.example.jp - パス : /entries/1

もう少し複雑なわざとらしいURIの例 `http://yohei:pass@blog.example.jp:8000/serach?q=test&debug=true#n10

  • URIスキーム : http
  • ユーザ情報 : yohei;pass
  • ホスト名 : blog.example.jp
  • ポート番号 : 8000
  • パス : /search
  • クエリパラメータ : q=test&debug=true
  • URIフラグメント : #n10

URIの設計について

良いURIやきれいなURIのことを「クールURI」と呼びます。 起源はWebの発明者Tim Berners-Leeが1998年に発表した「Cool URIs don't change」というWebページです。 当時はURIが変更になることが日常茶飯事で、リンク切れが頻発していました。

クールなURI,つまり変わりにくいURIにするための設計手法について記載されています。

実装依存を排除し、できるだけシンプルにすればURIを変更しにくくなります。
また、シンプルにすることで覚えやすく使いやすいURIになります。

URIは次の点でとても重要です。

  • URIはリソースの名前である
  • 寿命が長い
  • URIはブラウザがアドレス欄に表示する

第三部 HTTP

HTTPとは

TCP/IPをベースとしたプロトコル
RFC2616で規定している1.1というバージョンが最新バージョンで現在も使われている。
Hypertext Transfer Protocolという名前で、名前こそハイパーテキストの転送用プロトコルだが、ハイパーテキスト以外にもコンピュータで扱えるデータであればなんでも転送できる。

代表的なプロトコル

TCP/IP

HTTPはTCP/IPをベースにしている。

TCP(Transmission Control)とIP(Internet Protocol)についての説明がありますがここでは割愛します。

HTTP1.1について

HTTP0.9(誕生時のHTTP)、HTTP1.0(最初の標準化)についての説明がありますがここでは割愛します。

HTTP1.1がこの書籍で主に解説されている仕様です。

RFC2068として1997年に策定されました。 現在はRFC2616が発行されていて、現在のHTTP1.1の仕様が策定されています。

個人的にはこのRFC2616から更新されることなく利用され続けている点がHTTPの設計のすごさだと感じました。 新しいバージョンのHTTPを定義しようとした活動はいくつか存在したらしいです。

クライアント/サーバ

Webで採用されているアーキテクチャスタイルはクライアント/サーバです。 クライアント(Webブラウザ)が情報を提供するサーバ(Webサーバ)に接続し、リクエストを送信してレスポンスを受け取る仕組みです。

HTTPメッセージ

リクエストとレスポンスのメッセージ構文についての解説があります。 仕様の解説なので割愛しますがここの部分に関してはメッセージがどういうふうに使われるのか、実際に送信されるメッセージなどを参考にしながら理解を進めました。 また、以下のサイトを同時に見たりして理解しました。 https://developer.mozilla.org/ja/docs/Web/HTTP/Messages

ステートレスとは

ステートレスとは「サーバがクライアントのアプリケーション状態を保存しない」制約のこと。 また、わかりやすい例も紹介されています。 ハンバーガーショップでの注文を例題に解説されていますが、最後のまとめの部分がわかりやすかったです。

  • ステートレスなやりとりでは、クライアントは毎回全ての注文を繰り返している。
  • ステーツフルなやりとりでは、サーバがクライアントのそれまでの注文を覚えている。

ステートフルの欠点...状態を保存せざるを得ないため、クライアントの数が増えた際にスケールアウトさせにくい

HTTPメソッドについて

  • 他のメソッドでは対応できない処理はPOSTでできる
  • が、行きすぎると誤用につながる
  • 他に適切ねメソッドが用意されている場合はそちらを使う

XML-RPCSOAPは誤用

メソッド 性質
GET,HEAD べき等かつ安全
PUT,DELETE べき等だが安全でない
POST べき等でも安全でもない

べき等とは...ある操作を何回行っても結果が同じこと

ただ、誤った使い方をして安全性を破壊する使い方をしている場合もある。 例えば、GETの場合、

GET /resources/1/delete HTTP/1.1
Host: example.jp

のような本来の目的である「リソースの取得」を完全に無視した使い方ができる。 上記テーブルの性質を満たせているか確認する必要がある。

  • webの成功理由はHTTPメソッドにある。
    • RESTの統一インタフェース規約として数少ないメソッドしか定義されていないが、メソッドを限定したからこそプロトコルがシンプルに保たれ、webは成功した。(UNIXも似たような思想だった気がする)

ステータスコードについて

ステータスライン - レスポンスメッセージの1行目にあるステータスラインは、プロトコルバージョン、ステータスコード、テキストフレーズからなる。

HTTP/1.1 200 OK

この例の場合は200ステータスコード。 200はクライアントのリクエストが正常終了したことを示す。

ステータスコードの分類

EFC2616の6.1.1節で定義されている。

  • 1xx : 処理中
    処理が継続中。クライアントはそのままリクエストを継続するか、サーバーの指示に従ってプロトコルをアップデートして再送信する
  • 2xx : 成功
    リクエストが成功したことを示す。
  • 3xx : リダイレクト
    他のリソースへのリダイレクトを示す。クライアントはこのステータスコードを受け取った時、レスポンスメッセージのLocationヘッダを見て新しいリソースへ接続する。
  • 4xx : クライアントエラー クライアントのリクエストに原因のあるエラー。エラーを解消しない限り正常な結果が得られないので、同じリクエストをそのまま再送信することはできない
  • 5xx : サーバーエラー
    サーバー側が原因のエラー。サーバ側の原因が解決すれば、同一のリクエストを再送信して正常な結果が得られる可能性がある。

第四部 ハイパーメディアフォーマット

以下項目についての説明があります。
が、仕様の解説が大半のため割愛したいと思います。

第五部 Webサービスの設計

これまで学んだ仕様等を使って具体的な例を挙げながらRestful APIの設計を行います。
郵便番号検索サービスを例にWebサービスの設計について解説されています。

この第五部が本書の一番の肝であるとともに難易度も高めの箇所なのかなと思っています。
リソース設計(クライアントとサーバの間のインタフェースの設計)をメインに解説されています。

この部分については書籍の一番重要な部分であるので要約は避けたいという考えと、
個人的にAPI設計の経験が浅くまだまだ理解が必要な部分だと感じるため割愛させていただきます。