logo
Published on

Scrapbox: Webを支える技術

Authors

書籍: 『Webを支える技術』

目的

本書では「WebサービスをいかにWebらしく設計するか」をテーマに、Webサービスにおける設計課題を解説する。 -> 連携性が高く、拡張性も高いもの そのために、以下の2つの視点で読み進める

  1. Webサービスで使用される技術の仕様を理解する
  2. Webサービスの設計方法を理解する

仕様を知るだけでは良いものは作れないが、仕様を知らないと良いものは作れない。 そのためにまずはWebで使用される技術の基礎を学び、その上でその技術を用いてWebサービスを設計する方法を学ぶ。

第1部: Web概論

  • Webを支える最も基本的な技術
    • HTTP(Hyper Text Transfer Protocol)
    • URI(Uniform Resource Identifier)
    • HTML(Hyper Text Markup Language)
  • Webの2つの側面
    • ハイパーメディアシステム(Hypermedia System)
      • テキストや画像、音声、動画などのメディアをハイパーリンクで結びつけて構成したシステム
      • ハイパーリンクとは、ハイパーメディアにおいて情報同士を結びつける機構のこと
    • 分散システム(Distributed System)
      • 複数のコンピュータやプログラムをネットワーク上に分散して配置し、1台のコンピュータで実行するよりも効率的に処理できるようにしたシステム
  • 1993年にイリノイ大学のNCSA(National Center for Supercomputing Applications)で開発されたMosaicがWebブラウザの普及を促し、Webが一般に普及するようになった
  • Mosacの登場後、大手ベンダーが参入してブラウザ開発競争が勃発する中で、Web構成する技術で標準化の動きが進んだ
    • 1994年にWeb技術を実装している各社が集まって標準化を行う団体W3C(World Wide Web Consortium)が設立された
  • W3CではHTMLやCSS、XML、HTTPなどのWeb技術の標準化を行っている
  • REST: ロイ・フィールディング(Roy Fielding)が2000年に博士論文で提唱したWebのアーキテクチャスタイル
  • SOAP vs REST
    • SOAP(Simple Object Access Protocol)
      • Webサービスの通信プロトコルの1つで、メッセージ転送の方法のみを定めた仕様
      • 実際にシステムを構築する際にはSOAPの上にサービスごとのプロトコルを定義する必要があった
        • このプロトコルの仕様が複数乱立してしまい、SOAPの普及を阻害する要因となった
    • ロイ・フィールディング等がRESTを押す一方で、当初は大手ベンダーが自社の使用するプロトコルを標準化しようとSOAPの仕様策定が進んだ
    • GoogleやAmazonといった企業がRESTでのWebAPIを提供するようになり、最終的にはRESTが普及するようになった
  • 2004年から始まったWeb2.0の流れの中で、マッシュアップ(Mashup)=いろいろなWebAPIが提供する情報を組み合わせて1つのアプリケーションを実現するという手法が重視され、RESTが注目されるようになった
  • REST = Webのアーキテクチャスタイル
    • アーキテクチャスタイル: 複数のアーキテクチャに共通する性質、様式、作法あるいは流儀を指す言葉であり、特定の実装やアーキテクチャではない。アーキテクチャから抽象度を1つ上げたもの
    • アーキテクチャ: アーキテクチャスタイルを用いて作成されたシステムの設計で、実装から抽象を1つ上げたもの
    • リソース(resource)
      • Web上に存在する、名前を持ったありとあらゆる情報のこと
      • リソースの名前とは、URIを指す
        • URIは構造を持っており、プログラムで簡単に処理できる
        • URIが備えるリソースを簡単に指し示せる性質のことを「アドレス可能性(Addressability)」という
      • サーバとクライアントの間でやりとりするデータのことを「リソースの表現(Resource Representation)」という
  • RESTのアーキテクチャスタイル = 6つのアーキテクチャスタイルを組み合わせたもの
    • クライアント/サーバ
      • 処理をクライアントとサーバに分離することで、クライアントをマルチプラットフォームにでき、サーバを複数サーバを組み合わせて冗長化し可用性を高めることができる
    • ステートレス
      • クライアントのアプリケーション状態をサーバで管理しないこと
      • サーバの実装を簡略化できる
      • 現実的にはCookieを使ってステートフルなWebサービスも多い
    • キャッシュ
      • リソースの鮮度に基づいて、一度取得したリソースをクライアント側で使いまわす方式
      • サーバとクライアント間の通信を減らすことでネットワーク帯域の利用や処理時間を縮小し、より効率的に処理できる
    • 統一インターフェース
      • URIで指し示したリソースに対する操作を統一した限定的なインターフェースで行うアーキテクチャスタイルのこと
      • HTTP1.1ではGETやPOSTなど8個のメソッドだけが定義されている
      • インターフェースの柔軟性に制限を加えることで全体のアーキテクチャがシンプルになるし、インターフェースを統一することでクライアントとサーバの実装の独立性が向上する
      • RESTを最も特徴づけるアーキテクチャスタイル
        • 現在のWebがさまざまなクライアントやサーバの実装で構成されているのはこの統一インターフェースの存在が大きい
    • 階層化システム
      • システムをいくつかの階層に分離するアーキテクチャスタイル
      • サーバとクライアントの間にロードバランサを配置したりプロキシを配置することで、システム全体の性能を向上させることができる
    • コードオンデマンド(Code on Demand)
      • サーバからクライアントにプログラムを送信し、クライアントで実行するアーキテクチャスタイル
      • クライアントを後から拡張できる利点がある
      • WebブラウザでJavaScriptを実行する仕組みがこれに該当する
      • Loy Fieldingの論文ではRESTのアーキテクチャスタイルとしてはオプションであり必須ではないが、近年のWebでは必須に近い位置づけになっている

第2部: URI

  • URI(Uniform Resource Identifier): リソースを統一的に識別するID
  • URIの構文
    • URIスキーム: URIが使用するプロトコルを示す
    • ホスト名: DNS(Domain Name System)で解決できるホスト名かIPアドレスで、インターネット上で必ず一意
    • パス: 階層を表すパス
  • クエリパラメータ(query parameter)またはクエリ文字列(query string)
    • 1つ以上のクエリの集合のこと(クエリ: 名前=値形式の文字列)
    • クライアントから動的にURIを生成するときに利用する
  • 絶対URI: ルートから記述したパス
  • 相対URI: 現在のURIからの相対パス
  • ベースURI: 相対URIを解決するための基準となるURI
  • URIで使用できる文字列: ASCII文字列のみが使用できる
    • ASCII文字列以外を使用する場合はパーセントエンコーディング(URIエンコーディングともいう)を使用する
    • ひらがなの「あ」をURIとした場合、エンコーディングされると「%E3%81%82」と9文字になる
  • URIの長さ制限はないが、ブラウザの実装によって制限がある場合が存在する
  • WebサービスやWebAPIの実装においては、URIの仕様上気をつけるべきポイントは相対URIの解決とパーセントエンコーディング
  • URI/URL/URN
    • URI: リソースを識別するための識別子。正確にはURLとURNの総称
    • URL: リソースの場所を示すURI
    • URN: リソースの名前を示すURI
  • Berners-Leeの主張: 「URIは変わらないべきである。変わらないURIこそが最上のURIである」= クールなURI
  • URIを変わりにくくするために
    1. プログラミング言語に依存し他拡張子やパスを含めない
      • 最近の言語・フレームワークでは含まないことが多い
      • ただしユーザーの使用する言語によって表示するリソースを変えたい(日本語版、英語版等)場合には、拡張子で表現することがある
        • HTTPのコンテントネゴシエーションを使用し、サーバ側で返すリソースを変える方法もある
    2. メソッド名や動的に変わる値(セッションID等)を含まない
      • セッションIDはCookieに保存する
    3. URIはリソースを表現する名詞にする
      • URIとHTTPメソッドの関係は、名詞と動詞の関係であり、URIは全体として名詞となるように設計するべき
  • URIを変更したいとき場合には、できる限りリダイレクトをするなどユーザーにとって負担やストレスにならない方法を考える
  • URIはスラッシュを用いて階層表現するが、地図等の複数パラメータを組み合わせて表現するリソースにはマトリクスURI(Matrix URI)を使用することがある
    • マトリクスURI: URIのパスの途中にセミコロンやカンマを使ってパラメータを表現する方法
    • 現在では、セミコロン(;)はパラメータの順序が意味を持たない場合に使用され、カンマはパラメータの順序が意味を持つ場合に使用される
  • URIの不透明性
    • URIをクライアント側で組み立てたり拡張子からリソースの内容を推測できないようにすること
    • URIの不透明性を高くすることで、URIが変更されたときにクライアント側の変更が少なくて済む

第3部: HTTP

  • HTTP: RFC2616で定義されたWeb上でデータをやり取りするためのプロトコル
    • コンピュータで扱えるデータであればなんでも転送できる
    • クライアントが出したリクエストをサーバーで処理してレスポンスを返す、クライアント/サーバーのアーキテクチャスタイル
      • リクエスト/レスポンス型のプロトコル
    • ステートレス: クライアントとサーバーの間で状態を持たない
  • HTTPメッセージの構造
    • リクエストライン: リクエストの種類(GET/POST/PUT/DELETE等)、URI、HTTPバージョン
    • ヘッダ: リクエストやレスポンスに関する情報
    • ボディ: リクエストやレスポンスの本文
  • HTTPレスポンスメッセージの構造
    • ステータスライン: ステータスコード、ステータスメッセージ、HTTPバージョン
    • ヘッダ: レスポンスに関する情報。Content-TypeやContent-Length、文字エンコーディング方式などを指定
    • ボディ: レスポンスの本文。ヘッダとボディの間には空行が必要。バイナリデータも入れられる
  • HTTPメソッド8つ
    1. GET: リソースの取得
    2. POST: リソースの作成、リソースへのデータ追加、その他の処理
    3. PUT: リソースの更新、リソースの作成
    4. DELETE: リソースの削除
    5. HEAD: リソースのヘッダ情報の取得
    6. OPTIONS: サーバーがサポートしているメソッドの取得
    7. TRACE: リクエストのループバックテスト
    8. CONNECT: プロキシ経由での通信要求
  • HTTPメソッドと冪等性の関係
    • GET/HEAD: 冪等かつ安全
      • 何度実行しても結果は同じかつリソースは変更されない
    • PUT/DELETE: 冪等だが安全ではない
      • 何度実行しても結果は同じだが、リソースが変更される
    • POST: 冪等でも安全でもない
      • 複数回実行で結果が変わるし、リソースが変更される
    • 基本的には冪等性との関係は上記の通りだが、実際には実装によっては変わることもあるので実装面での注意は必要
  • ステータスコードを先頭の文字で分類する(1xx,2xx,3xx,4xx,5xx)ことでクライアントとサーバーの約束事を最小限に抑えて疎結合に
  • HTTP認証方式はHTTP1.1で規定するBasic認証、Digest認証の2つ
    • Basic認証: ユーザー名とパスワードをBase64でエンコードして送信する
      • Authorization: Basic base64encode(username:password)
      • 平文でユーザーネームとパスワードが流れるのでセキュリティは弱い
    • Digest認証: パスワードをMD5でハッシュ化して送信する
      • Basic認証よりはセキュリティが高い
      • クライアントからしてみると操作が複雑なのであまり普及していない
      • パスワードは暗号化されるがメッセージは平文のままなので、メッセージも暗号化したい場合にはHTTPSを使用する
  • HTTPのキャッシュ
    • サーバーから取得したリソースをローカルストレージに蓄積し、再利用する手法
    • ヘッダを活用して実現する
      • Pragma: キャッシュの抑制
        • no-cache という値を指定することでキャッシュを抑制する
      • Expires: キャッシュの有効期限を示す
        • キャッシュの有効期限を過ぎるとキャッシュを再取得する
      • Cache-Control: 詳細なキャッシュの制御
        • PragmaヘッダとExpiresヘッダの代替として使用できる
        • no-cache という値を指定することでキャッシュを抑制する
        • max-age という値を指定することでキャッシュの有効期限を指定する
    • キャッシュ用ヘッダの使い分け
      • キャッシュをさせない場合: PragmaとCache-Controlのno-cacheを同時に指定
      • キャッシュの有効期限が明確: Expiresを指定
      • キャッシュの有効期限を相対的に指定したい: Cache-Controlのmax-ageで相対時間を指定
  • HTTPの持続的接続
    • HTTP1.0では1リクエストごとに接続を切断していたが、HTTP1.1では1つの接続で複数のリクエストを処理できるようになった
    • Keep-Aliveヘッダを使用して持続的接続を行う

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

HTML(Hyper Text Markup Language): タグで文書の構造を表現するためのコンピュータ言語

  • 初期のHTMLはBerners-LeeがSGML(Standard Generalized Markup Language)をベースに開発した
    • SGMLは複雑で扱いにくかったため仕様をシンプルにしたXMLが開発された
  • HTML4.01をSGMLからXMLベースに変更したものがXHTML1.0
  • メディアタイプはtext/htmlapplication/xhtml+xmlの2つがある
    • text/htmlはHTML4.01以前のバージョンを指す
    • application/xhtml+xmlはXHTML1.0以降のバージョンを指す
  • XML
    • 文書を木構造として表現
    • 要素で文書の構造を表現し、開始タグと内容、終了タグで要素を表現
  • HTMLの構成要素
    • ヘッダ: 文書のメタデータを記述
    • ボディ: 文書の本文を記述
      • ブロックレベル要素(Block Level Element)とインライン要素(Inline Element)に分けられる
        • ブロックレベル要素: 1行全体を占める要素
        • インライン要素: 1行の中で一部を占める要素
  • HTMLにおけるリンク
    • <link>要素
      • HTMLのヘッダでWebページ同士の関係を指定する
      <link rel="stylesheet" type="text/css" href="style.css">
      
    • フォーム
      • リンク先のURIに対してGET/POSTリクエストを送信する
        • フォームによるGETはキーワード検索などユーザーからの入力によってURIを生成するときに利用する
        • フォームによるPOSTはリソースの作成などユーザーの入力をターゲットとなるURIに送信するときに利用
    • rel属性
      • リンク元のリソースとリンク先のリソースがどのような関係にあるかを記述する
      <link rel="stylesheet" href="https://example.com/base.css">
      <a href="http://example.com" rel="nofollow">リンク</a>
      

第5部: Webサービスの設計