「Webを支える技術」の内容のまとめ

# はじめに
今回は「Webを支える技術」という本を読んだのでその本の内容について自分なりにまとめていきたいと思う。初心者には難しい本でしたがWebのことについて幅広く学べるいい本だった。
[Webを支える技術 Amazon](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の歴史などはまとめていない。
## 第1部 Web概論
現在のコンピューターにおいて最も重要なソフトフェア ⇨ Webを観覧するソフトウェア、**ブラウザ(Browser)**。

### Webについて
**Webの用途は主に3つ**

* Webサイト

　最も身近な例(Googleの検索サイト、Amazonのショッピングサイトなど)。

* ユーザーインターフェースとしてのWeb

　人間向けのインターフェース。
　Webはユーザーインターフェース(UI)の分野でも使われる。
　ルーターやテレビ、ハードディスクレコーダ、プリンタなど、ネットワークに接続するデバイス設定。

* プログラム用APIとしてのWeb(Web API)

　プログラム向けのインターフェース。
　XMLやJSONなど

**Webを支える技術(HTTP/URI/HTML)**
*URI*は世界中のあらゆる情報を指し示せる。
*HTML*はそれらの情報を表現する文書フォーマット。
*HTTP*というプロトコルを使って、それらの情報を取得、発注したりする。

シンプルな技術。HTTP1.1が定義しているメソッドは8つ。
HTTP,URI,HTMLに支えられたWebは、 *ハイパーメディアシステム* と *分散システム*。

**ハイパーメディアシステム**
テキストや画像、音声、映像など様々なメディアをハイパーリンクで結び付けて構成したシステム。

**分散システム**

* 1つの中央コンピュータが全てを処理する形式を「集中システム」
* 複数のコンピュータを組み合わせて処理を分散させる形式「分散システム」

集中システムより分散システムのほうが難しい機能や性能を実現できる。

アーキテクチャ ⇨ コンピュータやソフトウェア、システム、あるいはそれらの構成要素などにおける、基本設計や共通仕様、設計思想など。
WebのアーキテクチャはRESTが普及。

### RESTについて
RESTはWebのアーキテクチャ、設計思想。

**RESTにおける重要な概念の一つ リソース**
Web上に存在する、名前を持ったありとあらゆる情報。
リスースの名前はURIのこと。1つのリソースは複数のURIを持てる。

RESTとは次の6つを組み合わせたアーキテクチャスタイルのこと

1. クライアント/サーバ
2. ステートレスサーバ
3. キャッシュ
4. 統一インターフェース  
5. 階層化システム
6. コードオンデマンド


❶ネットワークシステムのアーキテクチャ。ネットワークで有名なアーキテクチャは **クライアント/サーバ**。
WebのアーキテクチャはRESTでもあり、クライアント/サーバ。
一人一人が作る個別のWebサービスやWeb APIでもRESTの約束を守ることが重要。

クライアントとサーバは分離して処理できる。
ユーザーインターフェースはクライアント担当。
データストレージとしての機能はサーバ担当。


❷クライアント/サーバに最初に追加するアーキテクチャスタイルは **ステートレスサーバ**。
ステートレスとは、クライアントのアプリケーション状態をサーバで管理しないこと。
メリット：サーバ側の機能を簡略化できる。
ステートレスではないWebサービス、WebAPI：Cookieを使ったセッション管理など

クライアント/サーバ ＋ ステートレス性 = クライアント/ステートレスサーバ


❸次のアーキテクチャスタイルは **キャッシュ**。
リソースの鮮度に基づいて、一度取得したリソースをクライアント側で使い回す方式。
メリット：サーバとクライアントの間の通信を減らせる。効率的に処理できる。
デメリット：古いキャッシュを利用してしまい、情報の信頼性が下がる。


❹次のアーキテクチャスタイルは **統一インターフェース**。
URIで指し示したリソースに対する操作を、統一した限定的なインターフェースで行うこと。
HTTP1.1ではGET,POSTなど8個のメソッドしか定義されなくて、増えない。
RESTで最も特徴づけるアーキテクチャスタイル。

利点：システム全体が階層化しやすい


❺システムをいくつか階層に分離するアーキテクチャスタイルを *階層化システム*
階層化システムを追加したアーキテクチャスタイル「統一/階層化/クライアント/キャッシュ/ステートレスサーバ」


❻次のアーキテクチャスタイルは **コードオンデマンド**。
プログラムコードをサーバからダウンロードし、クライアント側でそれを実行するアーキテクチャスタイル。
例：JavaScript,Flash,Javaアプレットなど
利点：クライアントを後から拡張できる。

コーデオンデマンドを追加したアーキテクチャスタイル「統一/階層化/コードオンデマンド/クライアント/キャッシュ/ステートレスサーバ」


クライアント/サーバにコードオンデマンドまでを追加した複合アーキテクチャスタイル **ULCODC$SS** = **REST**。
サーバを介さずに通信が必要な場合：REST以外のアーキテクチャスタイルのP2Pがいい

リソースをリンクで接続することで1つのアプリケーションを構成する考え方はRESTの基幹をなす思想：接続性
## 第2部 URI
URIとは「リソースを統一的に識別するID」

### URIについて

URIの構成パーツ(http://blog.example.jp/entries/1)
* URIスキーム:https
* ホスト名   :blog.example.jp
* パス       :/entries/1

URIには絶対URIと相対URIがある。

URIで使用できる文字

* アルファベット
* 数字
* 記号
* それ以外の文字はエンコーディングされる

URIの長さ制限はない。Internet Explorerは2,038バイト。

### URI設計
クールURI「URIは変わらないべきである。変わらないURIこそが最上のURI」

* プログラミング言語に依存した拡張子やパスを含めない(.pl、.rb、.do、.jspなど)
* 実装依存のパス名を利用しない(cgi-bin、servletなど)
* メソッド名やセッションIDを含めない
* URIはリソースを表現する名詞にする
* 覚えやすく、開発者ではない普通の人にも使いやすい(文字数が短かったり、馴染みのある単語にしたり)

URIを変更するときは古いURIを新しいURIにリダイレクトする。

* 言語などは拡張子で指定するといい(press.ja/press.en)
* スラッシュ(/)を使って階層を表現(2015/12/11)

URI発議の点で重要

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

## 第3部 HTTP
HTTPはTCP／IPをベースとしたプロトコル。

HTMLやXMLなどのハイパーテキストだけでなく、静止画、音声、動画、JavaScriptプログラム、PDFや各種オフィスドキュメントファイルなど、コンピュータで扱えるデータであればなんでも転送できる。
統一インターフェース、ステートレスサーバ、キャッシュなどを実現している、Webの基盤となるプロトコル。

### TCP/IPとは
インターネットの基盤を構成する重要なネットワークプロトコル。
インターネットのネットワークプロトコルは階層型 **[階層方プロトコル]**

* ネットワークインターフェース層
  一番下。物理的なケーブルやネットワークアダプタに相当する部分。
* インターネット層
  ネットワークでデータを実際にやり取りする部分。TCP/IPでIPが相当。
  IPはデータの基本的な通信単位 *「パケット」* と呼ばれる。
  IPはデータを送り出すことだけを保証。それが届くかどうかは保証しない。
* トランスポート層
  IPが保証しなかったデータの転送を保証。TCP/IPでTCPが相当。
  TCPは接続先の相手に対してコネクションを張る。データの抜け漏れをチェックし、データの到達保証。
  転送するデータがどのアプリケーションに渡るかを決定するのが *ポート番号*(1~65535の数値)。
* アプリケーション層
  具体的なインターネットアプリケーション。例：メールやDNS、HTTPを実現する層。
  TCPでプログラムを作るときは *ソケット(Socket)* と呼ばれるライブラリを使うことが一般的。
  ソケットはネットワークでのデータのやり取りを象徴化したAPI[接続、送信、受信、切断など]

HTTPはクライアントが出したリクエストをサーバで処理してレスポンスを返す。このことをリクエスト/レスポンス型のプロトコル。

**クライアントで行われること**

1. リクエストメッセージの構築
2. リクエストメッセージの送信
3. (レスポンスが返るまで待機)
4. レスポンスメッセージの受信
5. レスポンスメッセージの解析
6. クライアントの目的を達成するために必要な処理

**サーバで行われること**

1. (リクエストの待機)
2. リクエストメッセージの受信
3. リクエストメッセージの解析
4. 適切なアプリケーションプログラムへの処理の委譲
5. アプリケーションプログラムから結果を取得
6. レスポンスメッセージの構築
7. レスポンスメッセージの送信

リクエストメッセージ + レスポンスメッセージ = HTTPメッセージ

**HTTPはステートレス性**

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

システムにログインしてからログアウトするまでの一連の操作を *セッション*。
アプリケーション状態は別名「セッション状態」
アプリケーション状態とセッション状態はほぼ同じ意味。

ステートフルなプロトコル例：FTP(FTPサーバをログアウトするまで、クライアントがどのディレクトリにいるかといったアプリケーション状態をサーバが管理)

ステートフル欠点：クライアント数が増えるにしたがって、アプリケーション状態を覚えることが難しくなる。
ステートレス利点：アプリケーション状態を覚えないからサーバ側のシステムが単純になる。
ステートレス欠点：送信するデータ量が多くなる。認証など、サーバに負荷がかかる処理を繰り返す。通信エラーへの対処が難しい。

### HTTPメソッドとは
HTTPメソッドはクライアントが行いたい処理をサーバに伝える任務。8つしかない(主に使うのは5,6)

HTTPメソッドは「GET,POST,PUT,DELETE」の4つで **CRUD[Create(作成)、Read(読み込み)、Update(更新)、Delete(削除)]** 。

* GET指定したURIの情報を取得。最も利用頻度の高いメソッド。
* POSTはGETについで利用頻度の高いメソッド。役割は3つ
    1. 子リソースの作成(新しく子リソースを作成できる)
    2. リソースへのデータの追加(リソースへのデータ追加ができる)
    3. ほかのメソッドでは対応できない処理(いろいろある)
* PUTはリソースの内容の更新とリソースの作成の2つ
    1. リソースの更新(リソースを更新した結果が入る)
    2. リソースの作成(リソースを作成できる)

POST:TwitterのようにつぶやきのURIをサーバ側で自動的に決定するWebサービス。
PUT:Wikiのようにクライアントが決めたタイトルがそのままURIになるWebサービス。
基本的にリソースの作成はPOSTでURIもサーバ側で決定する場合はPUT

* DELETEはリソースを削除するメソッド。
* HEADはGETに似てる。リソースのヘッダだけを取得する。ボディが含まれない。
* OPTIONSはリソースがサポートしているメソッドの一覧を返す。

べき等「ある操作を何回行っても結果が同じこと」
安全「操作対象海苔ソースの状態を変化させないこと」

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


※メソッドの誤用によって、メソッドが安全でなくなったり、べき等でなくなったりする可能性はある

### ステータスコード
全てのリクエストにはレスポンスが返る。レスポンスメッセージの中で、意味を伝えるのがステータスコード。詳しいやつは調べる。ステータスコードを意識しながら設計することが大事!!

* 1xx:処理中
* 2xx:成功
* 3xx:リダイレクト
* 4xx:クライアントエラー
* 5xx:サーバエラー

### HTTPヘッダ
ヘッダは、メッセージのボディに対する付加的な情報、メタデータを表現。
リソースへのアクセス権を設定する認証や、クライアントとサーバの通信回数と量を減らすキャッシュなどのHTTPの機能はヘッダで実現。

メッセージでやりとりするリソースの表現の種類を指定するのが「MIMEメディアタイプ」
クライアントと交渉して決めること「コンテントネゴシエーション」

HTTPの認証方式はBasic認証とDigest認証。Web APIではWSSE認証がある。

* Basic認証はユーザ名とパスワードによる認証方式。
* Digest認証はBasic認証よりもセキュアな認証方式。いろいろ複雑(ここは読み込むか調べて)。

Digest認証利点：パスワードを盗まれる危険はない。パスワードをサーバに預けなくても良い。セキュリティリスクを下げる大きな優位点。
Digest認証欠点：メッセージ自体は平文でネットワーク上に流れる。HTTPSを利用しろ。サーバからのnonceがないとクライアント側でダイジェスト計算ができない。
* WSSE認証はHTTP1.1の標準外の認証方式。AtomPubなどのWebAPIの認証に使われる。Basic認証とDigest認証の中間認証方式。

**HTTPの重要な機能のキャッシュ**
サーバから取得したリソースをローカルストレージに蓄積し、再利用する手方。

キャッシュのための情報を提供するヘッダは3種類

* Pragma(キャッシュを抑制する)
* Expires(キャッシュの有効期限を示す)
* Cache-Control(詳細なキャッシュ方法を指定する)


HTTPヘッダを学ぶためには多様な知識が必要。上手に使うためには、歴史と実際のサーバやブラウザの実装を調査する能力が必要。

## 第4部 ハイパーメディアフォーマット
　WebサービスやWeb APIを設計するときに利用できる主要なハイパーメディアフォーマットの解説。

### HTML
(HTMLに関してはそれほどまとめない)
HTMLのメディアタイプは「text/html」と「application/xhtml+xml」の2つ。
「text/html」はSGMLベースのHTML
「application/xhtml+xml」はXMLベースのXHTML。

XML文書は木構造として表現。要素で文書の構造を表現。入れ子構造

名前空間：名前の衝突を防ぐ目的
xmlns:接頭辞="名前空間"

デフォルトの名前空間(Atom)
thrという接頭辞で宣言した名前空間(Atom Threading Extensions)
thr=ローカル属性

**HTMLの構成要素**

* ヘッダ(title,link,scriptなど)
* ボディ(ブロックレベル要素[文書の段落や見出しなど]とインライン要素[強調や改行など]に分かれる)
* 共通の属性(id属性,class属性)

**ハイパーメディアフォーマットとしてのHTML**

* a要素--アンカー
* link要素
* オブジェクト屁の埋め込み(画像の<img>要素,そのほかの<object>要素)
* フォーム(GETとPOSTが発行できる)

リンクの意味をプログラムが可読な状態で記述するための機構を用意
rel属性(リンク関係)やmicroformats

### microformats
HTMLの中でさらに意味のあるデータを表現するための技術がmicroformats。(リンクの細かい意味やイベント情報を表現)

セマンティクス(意味論)・・・人間が読んで理解するWebページの意味をプログラムからも処理できるように形式的に意味を記述するための技術

RDF・・・リソースの意味を厳密に記述できる汎用的なフレームワーク
RDFはいろいろ問題点(記述が複雑、統一的な記述がしづらい、対象データとは独立したメタデータが必要)があり、普及しなかった。

RDFの問題点を解消した技術がmicroformats(HTML文書そのものにメタデータを埋め込む技術)。
microformatsは *elemental(単純)microformats* と *compound(複合)microformats* の2つに分かれる。

代表的なフォーマット説明は調べて。
**elemental microformats**・・・リンク関係(a要素やlink要素など)を使ってメタデータを表現するフォーマット
**compound microformats**・・・主にclass属性を使って階層構造のあるメタデータを表現するフォーマット

microformats欠点：同じ値のclass属性やrel属性を持ったWebページがあったら、プログラムが誤認定を起こし、同じ属性値を持ったmicroformatsを作れなくなる。
RDFaでmicroformatsの欠点を解消できるが文書が複雑になるなどの問題は此方もある。

microformatsはHTMLの知識を持っていれば容易に習得できるし、既存のWebページに与える影響が少なくなる!!

### Atom
AtomはRFC4287が規定するブログなどの更新情報を配信するためのフィード。幅広い分野での応用が可能な汎用XMLフォーマット。
RSS・・・主にブログの新着情婦を伝えるフィード
Atom・・・ブログだけでなく検索エンジンや写真管理など様々なWebサービスのWeb APIとして利用。

Atomの構成要素はメンバリソースとコレクションリソースの2つ。
メンバリソース・・・Atomにおける最小のリソース単位。(ブログなら一つ一つの記事のこと)
コレクションリソース・・・複数のメンバリソースを含むリソース。

Atomのメディアタイプは「application/atom+xml」。typeパラメータで「entry」「feed」(それぞれの説明は省く)

Atomは拡張性の高さから、ブログ以外の様々なシステムで応用できる。
拡張要素はすべて「os」という接頭辞が示すOpenSearchの名前空間に属す。
詳しいAtomの拡張は省く。

* Atom Threading Extensions--スレッドを表現する
* Atom License Extension--ライセンス情報を表現する
* Feed Paging and Archiving--フィードを分割する
* OpenSearch--検索結果を表現する

Atomは多様なアプリケーション用の拡張が用意されたフォーマット。ブログ以外の用途でも用いられている。

### Atom Publishing Protocol(AtomPub)
Atom publishing protocolはブラウザ以外のWebクライアントからブログを投稿したり、システム同士を連携したりできるプロトコル。
Atom・・・データフォーマットの規定(フィード、エントリ)
AtomPub・・・Atomを利用したリソース編集プロトコルの規定。リソースの編集(CRUD操作)を実現する。
AtomPubの設計はRESTスタイルに基づいたプロトコル使用。

※AtomPubについてはここではあんまり説明しない

AtomPubに向いているWebAPI(筆者の考え)

* ブログサービスのAPI
* 検索機能を持つデータベースのAPI
* マルチメディアファイルのリポジトリのAPI
* タグを使ったソーシャルサービスのAPI

AtomPubに向いていないWebAPI(筆者の考え)

* Cometを利用するような、リアルタイム性が重要なAPI
* 映像のストリーム配信など、HTTP以外のプロトコルを必要とするAPI
* データの階層構造が重要なAPI
* 「たいとる」「作者」「更新日時」など、Atomフォーマットが用意するメタデータが不要なAPI

### JSON
今まで紹介したよりも軽量なデータ表現形式であるJSON。
XMLのように文書をマークアップすることには向いていない。
ハッシュや配列といったプログラミング言語から扱いやすいデータ構造を記述する。

JSONのメディアタイプは「application/json」
JSONのデータ型は6つ

* オブジェクト
* 配列
* 文字列
* 数値
* ブーリアン
* null

JSONはJavaScriptをベースにしたシンプルなデータフォーマット。JSONPを使うとクロスドメイン通信ができるからAjaxでは必須の技術。ハイパーメディアフォーマットとしても側面もある。


## 第5部 Webサービスの設計
今回はWebサービスの設計のことまでまとめない。今でもすごく多いのこれ以上まとめるとヤバそう。あと最後のWebサービスの設計は今までの部分をしっかり理解していないと無理なのでまずは第4部までをしっかり理解する。
いつか追加するかもしれない。