
読書記録。
読者プロフィール
組込み系エンジニア。
Web技術に触れるのはプライベートのみ。素人があれこれ試したりするくらい。大規模開発は未経験。14年前の前著は読んだ。プロになる予定は今のところない。
雑感
著者の主張である、技術を点ではなく線や面、はては立体的に理解することで技術の引き出しを作ろうという主張は全面的に同意でき、本書は常にこの主張を意識した構成となっている。具体的にはWWWの誕生から静的コンテンツ主体のWeb黎明期、動的コンテンツの増加、サーバサイドでの動的コンテンツの実現、Ajax(JavaScript)によるブレイクスルー、シングルページアプリケーション(SPA)への展開、と、Webの進歩の歴史をギュッとまとめてくれているのだが、それぞれの技術はぽっと出の一点ものではなく、課題や背景で深く関連づいたものであると示してくれている。
サンプルコードが多くすべて理解しようとすると大変だが、初回はサンプルコードを無視して流れを理解するような読み方が良いかも。総評としてはおすすめできる一冊と思う。
ページを行ったり来たりしなければ読み進めにくい構成と感じた点は惜しい。電子書籍ではなく紙で読むことをお勧めする。
あらすじ
全編通してTinyTodoというTODO管理アプリを教材にし、初期のWEBアプリケーション風の実装から現代のWEBアプリケーションへと形を変えていくような構成になっている。この教材の説明については割愛する。
WorldWideWebの歴史
ティム・バーナーズ=リーは「もしもあらゆる場所にあるコンピューターに蓄積されている情報がすべてリンクされたとしたら、地球上のすべてのコンピューター上の情報を誰もが手に入れられる情報空間が生まれるだろう」と予測し、このアイディアを温め続け1990年に最初のWEBサーバとWEBブラウザを開発した。
WWWを構成する重要な要素としてURL(本書ではURIと記載されているが分かり易くURLとしている)、HTTP、HTMLがある。これらの要素を仕様として定め、この仕様を中心に据えたことで多くのソフトウェア技術者がWWWに関わる機会が増え、急速に普及していく。
最小構成のHTTPサーバとクライアントの動作として、curlコマンドとncコマンドを用い、コマンドライン操作でHTTPサーバへのリクエストとレスポンスを確認した。またブラウザによるレンダリングを確認し、HTTPサーバそのものは非常にシンプルなものであると示されている。
動的なコンテンツからサーバ主体のWEBアプリケーションへ
HTTPサーバが静的なコンテンツを返すのではなく、サーバサイドでプログラムを実行し動的なコンテンツ生成を行うCGIが普及する。
初期のWEBアプリケーションはマルチページアプリケーション(MPA)で、複数の画面(add.htmlやlogin.html)を静的に備えていたが、画面遷移ごとに通信が発生するため通信が多くなってしまう構成であった。
またHTTPは状態を持たないステートレスなプロトコルであるが、一方でクライアント毎に異なる結果を表示するためにはクライアントの区別が必要であった。これを実現するクッキーについて具体的にどのように作用しているかを実例を通じて説明している。あるクライアントとサーバ間のやりとりであるセッションを区別するセッションIDについてフレームワークを用いずベタ実装することでクッキーの動作イメージを得られるよう工夫されている。
クッキーについては本書ではファーストクッキー、つまりクライアントを区別するための仕組みとして実装・説明されている。「クッキーって個人のWEB上での活動をトラッキングする悪名高いあれでしょ?」というのはサードパーティークッキーを用いたトラッキングである。本書ではクッキーに関する歴史と現在の詳細として以下のアドベントカレンダー記事を紹介している。WEB素人でもここまで読み進めた知識で理解でき、なかなか読ませる文章で面白い。
サーバ主体の従来型WEBアプリケーションの問題点とAjaxの登場
従来型のWEBアプリケーションの問題点として、【画面遷移が多く通信が頻発し、結果画面更新が遅い】という問題が挙げられている。従来型WEBアプリケーションは画面遷移や情報更新のたびにHTMLを取得するためであり、HTMLの取得を減らす=ブラウザでなんとかすることが求められていた。
そんな折に登場した技術がAjaxで、Ajaxを適用した具体的なアプリケーションとしてGoogleMapが説明されている。従来型WEBアプリケーションでGoogleMapを実現しようとすると地図画像が丸ごとダウンロードされ書き直すような作りとなるためどうしても速度が遅くなっていたが、JavaScriptによって動作した箇所のみに限定して地図を取得することができ、通信を減らすことができる。
またJavaScriptは非同期通信、つまりHTTPリクエストを送信し、レスポンスを待っている間にブラウザのレンダリングができるためユーザ体験を損なわないことができた。
非同期通信
非同期通信は一般的に記述が複雑になりプログラムの見通しが悪くなるものである。初期のコールバックのネスト地獄から始まり、Promiseによる同期通信風の記述までの発展の詳細が記載されている。なおPromiseにより記述をさらに推し進めたAsync/Awaitに関しては記述はされていない(はず)。
シングルページアプリケーション(SPA)
SPAとは、従来型WEBアプリケーションの課題を解決した現代のWEBアプリケーション形態とのこと。SPAとはHTTPサーバとの通信を最小にする構成で、具体的にはjavaScriptで表示更新を行い、サーバとのやりとりはデータ(JSON)のみとなる構成とのこと。クライアントサイドでHTMLの生成とレンダリングを行うため、クライアントサイドレンダリングと呼ばれる。
SPAの問題点 初期表示の遅さ
SPAの問題点として、初期表示後の画面更新は高速だが初期表示が遅いという問題がある。これは初回表示までにJavaScriptの取得、実行、レンダリングと多くの工程があるためである。この解決策として初期表示のみサーバサイドでHTMLを生成する(従来アプリケーションと同じ)とするSPA+サーバサイドレンダリング(SSR)がある。この実現のためにサーバサイドでもJavaScriptを実行できない場合非常に煩雑になることは想像に難くない。サーバサイドJavaScriptとはこのような用途でも有用である。
SPAの問題点 検索エンジンとの相性の悪さ
SPAにおいては静的なhtmlはindex.htmlのようなトップページのみで、子ページはすべて動的に生成される。そのためWEBクローラから見るとスカスカなサイトに見えてしまい、SPA初期においては検索インデックスを作成することができないという問題があった。これについてはGoogleのクローラの改善によりJavaScriptでレンダリングされったページであっても内容を読み取れるようになったため、改善傾向にあるとのこと。
なお子ページを識別する方法としてフラグメント(ブラウザ上のみで有効な表示位置情報。URLに#で記載される)を用いる方法とHistryAPIについて述べられている。HistryAPIとはブラウザ操作による画面遷移(バックなど)を阻害し、別処理に置き換えるような実装で用いるものであり、具体的なサンプルで示されている。
Web API
Web APIの歴史を紐解いている。RPC、CORBA、SORPといった技術や背景について述べている。紆余曲折を経てWeb APIのインターフェースの方針としてRESTが提唱された。RESTとはWEB設計のエッセンスを表現した設計指針である。RESTはあいまいさを含むため「どこまで対応したらRESTなのか?」という論争があったそう。本書ではRESTとして6つの特徴を述べているが、コードの説明などを通して私の理解としては特に以下の以下の2点が重要だと考えている(6つ全てについては説明不十分であるため書いても中途半端になるため、主観で記載している)
1、文章や画像といったリソースはURLで位置を示すことができる(アドレス可能性)
2、リソースの操作方法はGETやPOSTで行う(統一インターフェース)
具体的には以下のようにtodosというリソースに対して取得(GET)を行うと、レスポンスボディにJSON形式でtodosの一覧が得られるようなものである。
GET https://tinytodo-XX.webtech.littleforest.jp/todos
RESTの問題点
RESTはいってしまえばリソースに対するReadとWriteであり、Linuxではおなじみのインターフェイスである。意味が分かり易く、実装も容易であるというメリットがあるが、一方でAPIとしては粒度が小さすぎ要件を満たせない場合がある。例えばホテルの連泊予約をREST APIで行うと、一泊ごとに予約するような動作になってしまい、複数日にわたり安全に予約することは難しい。この対処としてGraphQLについて言及している。GraphQLに関してはサンプルと、RESTの考え方と対極に位置することが示されている。
同一オリジンポリシー
同一オリジンポリシーとはあるサイトから読み込まれたJavaScriptは別のサイトで制限がかかる機能を指す。これによって自身で公開したWeb APIであっても別のサイトからは使用することができない。これを回避するためにはサーバ側でオリジン間リソース共有(CROS)を許可する必要がある。これによってTinyTodoは例えばカレンダーアプリとの連携が可能となる。
サーバプッシュ技術
HTTPはクライアントが要求しサーバがレスポンスするものであるため、サーバ側から変化をプッシュ(コールバック)することができない。これによって変化を即時クライアントに反映することが困難であった。
歴史上登場したサーバプッシュ技術について述べられている、ポーリング、疑似的なサーバプッシュを経て、2005年にHTML5関連のAPIとして制定されたServer-sent event(SSE)がある。この実態は複雑であるが、TinyTodoの改造を通して具体的なサンプルコードで使用イメージが示されている。SSEにおいてクライアントはHTTP接続状態のままとし、サーバは必要な時にイベントを発行することで実現されている。
Web Sockert
HTTPというプロトコル自体は、双方向通信ができない、通信効率が悪いという課題を抱えている。Web利用の広がりにおいてこれらの課題が足かせとなることがある。Web Sockertはこれらを解決したプロトコルである。
一方でHTTPは非常に広く普及し、例えばロードバランサーなどはHTTPであることを前提に最適化されている。そのためWeb Sockertを別プロトコルとしてHTTPとは別ポートで通信すると通信経路で遮断されてしまう可能性があるとのこと。そこでHTTPとして通信を開始し、途中でプロトコルを変更するという手段を用いている。
課題と解決を繰り返し発展してきたWebである。既存の課題を解決するWeb Sockertではあるが、別の課題があり、本書では〆としてそれらの課題について言及している。