Sakiのプログラミング学習ブログ

プログラミングについて学んだことや、学習の振返りを書いています。

『Webを支える技術』を読んで学んだこと

f:id:Saki-Htr:20210228190546p:plain

フィヨルドブートキャンプの課題である、「Webを支える技術 -HTTP、URI、HTML、そしてREST」(以下、「Webを支える技術」)」を、techplay女子部で輪読会をして読み終わったので、REST,URI,HTTPを中心に学んだこと・感想を書いた。

<<無断転載にならないよう気をつけて書いたつもりですが、もしご指摘等ありましたら修正あるいは削除させていただくつもりです>>

活動内容

  • 期間:11/15(日)〜12/24(木)
  • 人数:2人→途中から3人
  • ツール:zoom / HackMD
  • 時間帯:毎朝6:00~7:00 (起きられなかったら無し)
  • 形式:予習なしで、その場で読む。10分各自で読む&疑問や感想をHackMDに書く、次の10分で話し合い。これを3回繰り返して1時間。

本の構成

  • 第1部 Web概論
    • 第1章 Webとは何か
    • 第2章 Webの歴史
    • 第3章 REST
  • 第2部 URI
    • 第4章 URIの仕様
    • 第5章 URIの設計
  • 第3部
  • 第4部 ハイパーメディアフォーマット
  • 第5部

REST

アーキテクチャースタイルとは

RESTはクライアント/サーバーから派生したアーキテクチャースタイル

下記の文章の意味が理解できなかったので整理した。

実はRESTは、クライアント/サーバから派生したアーキテクチャスタイルなのです。素のクライアント/サーバアーキテクチャスタイルにいくつかの制約を加えていくと、RESTというアーキテクチャスタイルになります。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.26 より引用)

クライアント/サーバとは

  • アーキテクチャスタイルは、REST以外にも存在し、クライアント/サーバはその一つ
  • クライアント/サーバー:クライアントとサーバがHTTPというプロトコルで通信して、クライアントはサーバにリクエストを送り、サーバはそれに対してレスポンスを返してあげる方式
  • 単一のコンピュータ上ですべてを処理するのではなく、クライアントとサーバに分離して処理できることが利点。
  • RESTはこれに制約を加えたもの

制約とは

制約とは、以下の5つのアーキテクチャスタイルを指す。

  1. ステートレスサーバ

    • サーバー側で状態をもたない(リクエストする度毎回クライアントのことを忘れている/はじめまして)
    • HTTPをステートフルにするcookieはRESTの観点からすると、誤った拡張。しかし使わないわけにもいかないのが現状なので、必要最低限に使う。

  2. キャッシュ

    • 一度取得したリソースをクライアント側で使いまわす方式。
      例:「戻る」をクリックすると初めて接続したときより早い

  3. 統一インターフェース

    • インターフェースとは:プログラム同士の接点
    • 統一インターフェースとは:URLで示したリソースに対する操作を、統一した限定的なインターフェースで行う事。
    • メリット:インターフェースが統一されている事で、Webを利用しているシステムは同じHTTPメソッドで接続ができる。制限を加えることで、アーキテクチャをシンプルにできる。

  4. 階層化システム

  5. コードオンデマンド

    • プログラムコードをサーバからダウンロードし、クライアント側でそれを実行する
      例:JavaScript

結論

  • クライアント/サーバーというアーキテクチャスタイルに、この5つのアーキテクチャスタイル(制約)を加えたものがRESTである。
  • 実際にRESTに基づいて設計する時は、現実的にすべてのアーキテクチャスタイルを取り入れることができないこともあるため、いくつかを除外してもいい。

リソースとは

URI(URL)

クールなURIは変わらない

ブックマークに登録してあったお気に入りのWebサイトがある日突然見えなくなる、苦労して作成したリンク集が1年後には半分以上リンク切れ、検索エンジンの検索結果に出てくるページが見つからない
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.53より引用)

  • なんと、1990年代後半までは、URIが変更になることは日常茶飯事だった。=Webの根幹を揺るがす問題
  • Webはそれぞれのリソースにほかのリソースへのリンクが埋め込まれたハイパーメディアシステムなのに、リンクが切れてしまうということは、ハイパーメディアシステムが機能しないことになる。
  • Webの発明者ティム・バーナーズ=リーはこの状況を憂い、1998年に「Cool URIs don't change」(クールなURIは変わらない)」を発表した。

  • 自分が生まれたのが1995年なので、その頃にURLが変わっていてせっかくブクマ登録しても404になってしまう、という事態が信じられない...。

URIを変えないようにするための設計指針

 1. URIにプログラミング言語依存の拡張子を利用しない(.pl、.rb、.do、.jspなど)
 2. URIに実装依存のパス名を利用しない(cgibin、servletなど)
 3. URIにプログラミング言語のメソッド名を利用しない
 4. URIにセッションIDを含めない
 5. URIはそのリソースを表現する名詞である

(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.57 より引用)

指針について補足

  • 3.のメソッド名 = プログラミング言語のメソッドのことを言っている。(例)RubyのArrayクラスのsizeメソッド
  • CGIは廃れている
    Web技術の基本で学んだCGIが、この本では廃れた技術と書かれていた。2010年に発売した本なので2020年現在だと更に使われなくなっていそう。

    リクエストのたびにプロセスを起動するCGI方式は性能面で難点があったため、そのほかの手法に取って代わられました
    (山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.55より引用)

  • 4.のセッションIDが何かについては以下の記事で説明。

シンプルなURLは、ユーザーの使い勝手も良くする

  • シンプルだとその分文字数が少ないので、ユーザーが覚えやすい
  • 上記の1~5に該当しないURLは、ユーザーには馴染みがない

→文字数は少なく&シンプルにしよう。

階層で管理できない情報を表現したい時

  • 階層で管理できない情報を表現したいとき、例えばGoogleマップの位置情報を表現したいときは、マトリクスURIを使う。

地図中のある特定の場所を表現するURIには、緯度と経度のほかにも表示スケール(縮小・拡大)や地図か航空写真かのフラグなど、複数のパラメータが必要になります。しかもこれらのパラメータはそれぞれ独立した軸を持つため、個々のリソースを階層構造で表現できません。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.62より引用)

  • マトリクスURIは、複数のパラメ−タをセミコロン;で区切ってリソースを表現する。
http://hello.jp/map/lat=35.154328;lng=159.462784

URIが重要な理由

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

HTTP

HTTPのバージョン

アプリケーション状態とは

  • アプリケーション状態 = セッション状態
  • セッションとは:あるWebサイトにアクセス(あるいはWebシステムにログイン)して、ログアウトするかブラウザを閉じるまでが1セッション。1セッションで1ページしか閲覧しない場合もあれば、1セッションで何ページも見る場合もある。
  • セッション状態とは: 一連の操作の間の状態のこと。例:「ハンバーガーセットをポテトで注文している」という情報のこと。

HTTPメソッド

べき等性と安全性

  • べき等性:ある操作を何回行っても結果が同じであること。
  • 安全性:操作対象のリソースの状態を変化させないこと。 ※セキュリティ的な意味合いではないので注意。

→Webアプリを開発する時にこの2つがどう関わってくるのかイメージが湧かないので、今は「べき等性と安全性という性質がある」ということを覚えておく。

メソッドの間違った使い方

  • WebサービスやWebAPIの設計を誤ると、これらのメソッドが安全でなくなったり、べき等でなくなったりする
  • 例えば、GETの目的はリソースを取得することなのに、GETでリソースを更新したり、リソースを削除したりしてはダメ。
  • POSTは他のメソッドではできないことを色々できるが、他のメソッドでできることをPOSTにやらせてはいけない。
    特にGET,PUT,DELETEでできることをPOSTで行うとべき等性と安全性が損なわれる。
  • DELETEがべき等でなくなる例
    • /latestというURLがあり、「最新バージョンのリソース」を示すものだとする。
    • これをDELETEメソッドで削除すると、
    • 1回目:最新バージョンを消す
    • 2回目:1回目で消したバージョンの次に新しいバージョンを消す
    • 3回目:2回目で消したバージョンの次に新しいバージョンを消す...というようにエンドレスでバージョンを削除してしまう。

ステータスコード

ステータスコードの分類と意味

分類 意味
1xx 処理中
2xx 成功
3xx 他のリソースへリダイレクト
4xx クライアントエラー
5xx サーバエラー

ステータスコードは、クライアントとサーバーを疎結合にするための工夫

下記の文章の意味が理解できなかったので調べた。

ステータスコードを先頭の数字で分類するのは、クライアントとサーバの約束事を最小限に抑えて、クライアントとサーバの結び付きをなるべく緩やかにする、すなわち疎結合にするための工夫です。一般的に、システムが疎結合になると、コンポーネント間の独立性が高まり、コンポーネントの置き換えや拡張が容易になる、と言われています。HTTPで言えば、コンポーネントとはサーバとクライアントのことです。つまり、サーバのバージョンアップやクライアントの置き換えが行いやすい、ということです。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.113より引用)

疎結合とは

  • 疎結合と密結合という2つの概念がある。どちらも結合度(結びつきの強さ)を表す用語。コードでもこの2つの考え方がある。
  • 密結合
    • 処理を同一タイミングで行う場合に互いの処理同士の干渉が大きいもの。
    • コード同士が複雑に絡み合っている状態なので、長期的な保守を考えるのであればやめた方が良い。
  • 疎結合
    • 一緒に実現するコードが互いの干渉がなく一つ一つのクラス独立しているもの。
    • 将来的な拡張に柔軟に対応できて良い。

コンポーネントとは

  • 機器やソフトウェア、システムの構成する部品や要素。

結論

  • 本では「ステータスコードは、クライアントとサーバーを疎結合にするための工夫」と言っている。
    →たしかに、400番台だとクライアント側に原因があるエラー、500番台だとサーバー側に原因があるエラーというように、原因の所在がきっちりと分かれている
  • サーバーとクライアントが密結合だと、一方の何かを変えたい時にもう片方にも影響が出て処理が複雑そうだと思った。お互い独立している=疎結合である方が良い、ということだと解釈した。

ステータスコードは正しく割り当てる

  • Webサービス/WebAPIを開発するときに、ステータスコードを正しく割り当てないと、ブラウザ(クライアント)が間違った処理をしてしまうので、正しく割り当てることは最低限のマナー。
  • 例えば、本当は404 Not Found(リソースの不在)=エラーの状態なのに、404を返さず200 OK(リクエスト成功)を返す仕様にしているとする。
    これでは検索エンジンのロボットが404の状態をエラーでなく、正式なリソースと判断してしまう。
  • 開発しているWebサービスやWebAPIでエラーが起きたときに、どのステータスコードを返すかは、とても重要な設計の検討事項。とくに400番台は種類が多いので注意。

HTTPヘッダ

コンテントネゴシエーションとは

メディアタイプや文字エンコーディング、言語タグは、サーバが一方的に決定するだけではなく、クライアントと交渉(ネゴシエーション)して決めることもできます。この手法を「コンテントネゴシエーション」(ContentNegotiation)と呼びます。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.132より引用)

自分の言葉で説明してみた。

  • 英語と日本語の両方に対応しているサーバーに、日本語しか受け付けないリクエストをクライアントが送ると、日本語が返ってくる。
  • クライアント「日本語しか対応してないから日本語でよろしく」
  • サーバー「OK、日本語で返すね」

このやり取りのことを「交渉」と言っている。

キャッシュ用ヘッダ

  • HTTPの機能の一つ:キャッシュは、キャッシュ用ヘッダによって使える。
  • あるリソースがキャッシュ可能かどうかは、そのリソースを取得したときのヘッダで判断する。リソースがキャッシュ可能かどうか、その有効期限がいつまでなのかは、Pragma,Expires,CacheControlヘッダを用いてサーバが決める。

no-cashe=キャッシュ禁止ではない

  • 「キャッシュを使うな」という意味ではない。
  • 一度キャッシュに記録されたコンテンツは、現在でも有効か否かを本来のWebサーバに問い合わせて、確認がとれない限り再利用してはならない、という意味。

条件付きGET

以下の文章の理解が難しかったので、自分の言葉でまとめた。

クライアントがExpiresやCacheControlヘッダを検証した結果、ローカルキャッシュをそのまま再利用できないと判断した場合でも、条件付きGETを送信すればキャッシュを再利用できる可能性があります。条件付きGETは、サーバ側にあるリソースが、クライアントローカルのキャッシュから変更されているかどうかを調べるヒントをリクエストヘッダに含めることで、キャッシュがそのまま使えるかどうかを検証するしくみです。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.146より引用)

  • クライアントが自分のローカルストレージに保存しているキャッシュを再利用したいので、ExpiresやCacheControlヘッダを検証したら、no-casheだったので、サーバーがリソースのキャッシュを禁止=再度サーバーにアクセスしなくてはいけないことが分かる
  • no-casheと返されていても、「条件付きGET」を送信することで、自分のキャッシュが使えるかどうか調べることができる
  • 調べ方=サーバ側にあるリソースが、クライアントローカルのキャッシュから変更されているかどうかを調べるヒントを、リクエストヘッダに含める。
  • 調べ方には2つある。
    • If-Modified-Since (要求)ヘッダ
    • If-None-Match (要求)ヘッダ

HTML

rel属性

  • rel属性とは:リンク元のリソースとリンク先のリソースがどのような関係にあるか。
  • HTMLを書く時、意味を分かっていないで、rel="stylesheet"と書いていた。これは「元のHTMLリソースを外部のCSSリソースにリンクするとき」に書く。
  • stylesheet以外にも色んな例がある。

リソース設計

リソース設計の手順

  1. Webサービスで提供するデータを特定する
  2. データをリソースに分けるそして、各リソースに対して次の作業を行います。
  3. リソースにURIで名前を付ける
  4. クライアントに提供するリソースの表現を設計する
  5. リンクとフォームを利用してリソース同士を結び付ける
  6. イベントの標準的なコースを検討する
  7. エラーについて検討する

  8. リソース設計の最初の工程は、サービスで提供するデータを理解し特定する作業。

  9. 自分のサービスでどのようなデータを提供するのかを理解していなければ、リソースは設計できない。
  10. 日本郵便が提供してるCSVのデータ
    →会社で使ってるシステムが、郵便番号を入れても住所が自動で入力されないので、これを使って実装できそう

  11. 機能の結果をリソースとしてとらえることが、重要

クエリパラメータ

標準的な利用コースを検討する

  • 利用コースという言い回しが難しく感じる。
  • つまり、このWebサービスをクライアントがどんな目的をもって、何を知りたくて使うかを想定して、どういうリソースのたどり方(=利用コース)をするか
  • 今回は、郵便番号を入力して目的の郵便番号リソースを取得するコース(この郵便番号てどこの市町村だろう?)/住所を入力して郵便番号リソースを取得するコース/地域リソースの階層をたどりながら郵便番号を選択するコース
  • 利用する人の立場に立って考えなければいけない。

全体の感想

  • 『Web技術の基本』を先に読んでよかった。初めて読んだ時は、知らない用語ばかりでちんぷんかんぷんだったが、2回目は、アーキテクチャースタイル、REST,URI,HTTPの基本的な知識、リクエストとレスポンスの裏側で何が起こっているか、リクエストメッセージの構成、を事前に理解していたため、理解することができた。
  • メンターさんから、Ruby on Railsを触った後や、就職した後に読んでみると、 理解度が変わってくると伺ったので、今回はREST,URI,HTTPの理解を優先し、それ以外は、実務で使うことになったらまた戻ってこようという気持ちでサラッと読んだ。
  • 触ったことがある技術とない技術で、読んだときの理解度が全然ちがうなと思った。
  • 輪読会についての感想は以下にまとめた。 saki-htr.hatenablog.com

参考書籍・記事