あなただけの登山ルートがそこにはある『山頂をめざせ』:ボドゲ紹介
この記事何?
この記事は、 2016年ボドゲ紹介02 Advent Calendarの7日目です。
参加を決めてから気づきましたが、ボドゲ紹介01 の7日目は弊社のボドゲ部部長 @kano_e さんが書いていますので、そちらもどうぞ
今日紹介するゲームは、お気に入りなサイコロゲー「山頂をめざせ」です!
Gipfelstürmer: AMIGO - Familienspiel
- 出版社/メーカー: Amigo Spiel + Freizeit
- 発売日: 2015/10/01
- メディア: おもちゃ&ホビー
- この商品を含むブログを見る
まずは簡単にルールから
まずはじめに、1人5匹のヤギとプレートを一枚ずつ持ちます。
このヤギさんを山頂に進めるのがゲームの目的です!
この5匹のヤギを山の麓に並べてゲームスタート!
ターンが回ってくると、サイコロを5個振って各看板に書いてある目をクリアーできれば一歩前に進めます。 サイコロは振り直したいものだけキープして、振り直しは2回まで振り直せます。
例えばこの写真は、3と6のツーペアが揃っているので、
このツーペアの看板が進めるという感じでズンズンヤギさんを進めていきましょう!
自分のヤギさんを押し上げちゃえ
山頂までのルートにはヤギさんが止まる枠があるのですが、それには上限が決まっています。 小さい枠はみんなで1匹、大きい枠は個人で2匹までです。 じゃあ、それ以上は進めないのか?
ここがこのゲームの醍醐味! 自分のヤギを押し上げちゃう事ができるんです!!
上に行けば行くほど、看板の賽の目が難しくなるので、 このようになるべく道に続けるようにヤギを配置して、上に上に押し上げていくのがこの山頂をめざせの醍醐味です!!
相手を押しのけちゃえ
ゲームの中盤になると進む先に他の人のヤギがいる。。。という状況になります
その場合どうするか。。。。
邪魔な敵は押しのけていくのです!!!
上手くいけば、一番下まで突き落とすことができます!!
終了条件
こうして、ヤギさんを押し上げたり、敵を押しのけたりして、一番先に山頂に2匹のヤギさんを山頂に登らせたら勝ちです!!
あなたは白色ヤギさんや黄色ヤギさんみたいに準備万端に用意する派? [
それとも、緑色ヤギさんみたいに5つのぞろ目を気合いで出す派?
- どのルートを進ませるかという戦略
- 自分の力で出す目をコントロールする力
両方がバランス良く必要な、山頂をめざせいかかでしょうかo(・ω・´o) この日は着々とヤギさん並べてる間に6の5個ゾロ出されて負けましたw
おわりに
毎週水曜 19:30~ 弊社ボドゲ部活動中です! ほぼ毎週ゲストさんもいらっしゃっていますので、お時間ありましたらぜひ湯島まで〜
明日はowl_8 - Adventar の今年遊んだボドゲ です!
Webを支える技術を読んでる まとめ5
この記事について
技術研修で読み進めているWebを支える技術について、各章のまとめを順次上げていく。
HTTPヘッダとは
おさらい
Webを支える技術を研修で読んでる まとめ2 - pokotyamu的書きなぐり日記 メッセージヘッダーの部分が今回説明するHTTPヘッダである。
概要
ヘッダには、メッセージボディに対する付加情報(メタデータ)を入れる。 例えば、メディアタイプや言語タグなどである。 また、リソースへのアクセス権を設定する認証や、クライアントとサーバの通信回数と量を減らすキャッシュなどのHTTPの機能はヘッダで実現する。
つまりこのような機能は第7~8章で述べたHTTPメソッドやステータスコードと、本章のHTTPヘッダの組み合わせによって表現される。
本章では、 HTTP1.1で主に使用される頻度の高いものだけに絞って説明する。
歴史的背景
- HTTP0.9の頃には、HTTPヘッダは存在しなかった
- HTTPの仕様がバージョンアップするに連れ、本文のメタデータを表現するために電子メールのメッセージ仕様を使う方式が採用される
- そのため、現在のHTTPヘッダは電子メールのヘッダと同じものもある
- メールのメッセージ仕様は番兵構造である。^1
- メールは一方通行のやり取りだったが、HTTPは双方向にやり取りをするため拡張する必要がある
日時
DateやExpiresで表現する。 メッセージ作成の時間や、PUTやDELETEの時間指定などに使用される。 以下は主要な日時を使用するヘッダである。
利用するメッセージ | ヘッダ | 意味 |
---|---|---|
リクエストとレスポンス | Date | メッセージを作成した日時 |
リクエスト | If-Modified-Since | 条件付きGETでリソースの更新日時の指定 |
リクエスト | If-Unmodified-Since | 条件付きPUTやDELETEでリソースの更新日時の指定 |
レスポンス | Expries | レスポンスをキャッシュ出来る期限 |
レスポンス | Last-Modified | リソースを最後に更新した日時 |
レスポンス | Retry-After | 再度リクエストを送信出来るようになる日時の目安 |
Date: Tue, 06 Jun 2010 03:34:00 GMT
HTTPメソッドで使用する日時は、必ず GMT(グリニッジ標準時)で返さなければならない。
MIMEメディアタイプ
MIME(Multipurpose Internet Mail Extensions)の略。 名前の通り、電子メールのヘッダから採用されたものである。 今後はメディアタイプで示す。
Cotent-Type
メディアタイプの指定を行う。
Content-Type: text/plain
このメッセージボディの中身がどのような形式のものなのかを指定する。
メディアタイプには、以下の表の9つのタイプが存在している。
タイプ | 意味 | 例 |
---|---|---|
text | 人の読めるデータ | text/plain |
image | 画像データ | image/jpeg |
audio | 音声データ | audio/mpeg |
video | 動画データ | video/mp4 |
application | その他のデータ | aplication/pdf |
multipart | 複数データからなる複合データ | multipart/related |
message | 電子メール | message/rfc822 |
model | 複数次元で構成するモデルデータ | model/vrml |
example | 例示用データ | example/foo-bar |
text/plane
の/の左側を「タイプ」、右側を「サブタイプ」と呼ぶ。
タイプは勝手に増やすことは出来ないが、サブタイプは比較的自由に作ることが出来る。
サブタイプ一覧については数が膨大なので、IANAのページを参照する。
IANAは、「Internet Assigned Numbers Authority」の略。
ドメイン名、IPアドレス、プロトコル番号など、インターネット資源のグローバルな管理を行っている南カリフォルニア大学情報科学研究所のプロジェクトチーム。サブタイプの管理もここが行っている。
charset (日本語メッセージの注意)
文字エンコーディングを指定する。
Content-Type: application/xml; charset=utf-8
charsetは省略可能だが、タイプがtextの場合は注意が必要である。 HTTPでのtextタイプのデフォルト文字エンコーディングは、ISO 8859-1と定義されている。 もし、日本語文字列が入っているメッセージに対して、ISO 8859-1と解釈しようとするため、文字化けを引き起こす可能性がある。 さらに、メッセージボディ内で、文字エンコーディングを指定している場合でも、Conttent-Typeヘッダのcharsetが宣言されているならば、こちらが優先される。
文字化けを起こさないように気をつけるためには、必ずcharsetパラメータを付ける事が望ましい。
言語タグ
charsetパラメータは文字エンコーディング方式を指定するが、リソース表現の自然言語を指定する場合は、 Content-Languageを使用する。
Content-Language: ja-JP
言語タグの「-」の左側には、ISO 639が指定する言語コードが入る。 日本語ならば「jp」英語ならば「en」など 右側にはISO 3166が定義する地域コードが入る。 日本ならば「JP」アメリカならば「US」など
言語コードと地域コードの組み合わせにより、1つの国に複数言語ある場合や多数の国で使われる言語にも対応することができる。
コンテントネゴシエーション
メディアタイプや文字エンコーディングや言語タグはサーバが一方的に決定するだけでなく、クライアントと交渉して決めることも出来る。
クライアントが処理出来るメディアタイプを伝える時は、Accept
クライアントが処理できる文字エンコーディングを伝える時は、Accept-Charset
クライアントが処理できる言語を伝える時は、Accept-Language
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7 Accept-Language: ja,en-us;q=0.7,en=0.3
q=のパラメータは優先度が指定でき、1に近いほど優先される。 省略されている場合は1が入る。
Content-Length
Content-Length
ヘッダを利用して、メッセージボディのサイズを10進数のバイトで示すことが出来る。
静的ファイルなど、あらかじめサイズが分かっているリソースを転送する場合などは、これを利用する。
しかし、動的な画像ファイルなど、すぐにサイズが確定しない場合、Transfer-Encoding
ヘッダを利用して、ボディを複数の塊(チャンク)にして、転送することが出来る。
これにより、最終的なサイズが分からないデータに対しても、ボディを少しずつ転送することが出来る。
次にチャンク転送の例を示す。
POST /test HTTP/1.1 Host: example.jp Transfer-Encoding: chunked Content-Type: text/plain; charset=utf-8 10 The brown fox ju 10 mps quickly over e the lazy dog. 0 <空行>
各チャンクの先頭にはチャンクサイズが16進数で入る。 上記の例において、16バイトで表現する16進数の「10」と14バイトを表現する「e」が登場する。 最後には必ず長さ0の空行を付ける。
なお、HTTP1.1の仕様では、全てのHTTP1.1実装は、チャンクエンコーディングを受信しなければならない。
認証
概要
現在主流のHTTP認証方式には、HTTP1.1が規定しているBasic認証とDigest認証がある。 またWeb APIでWSSEというHTTP認証の拡張仕様を利用する場合もある。
今回は、主流の2つを簡潔に説明する。
そもそも認証について、あるリソースに制御がかかってる場合、401 UnauthorizedとWWW-Authenticate
ヘッダを利用して、クライアントにリソースへのアクセスに必要な認証情報を通知出来る。
DELETE /test HTTP/1.1 Host: example.jp
HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="Example.jp"
これは、Basic認証も、Digest認証もどちらも使用する。
Basic認証
最も簡単かつ基本的な方式。 ユーザ名とパスワードを使って認証を行う。
ブラウザから送信される認証情報は、「ユーザ名:パスワード」という形式で「:」区切りで並べ、これをBASE64でエンコーディングした文字列をHTTPヘッダのAuthorizationフィールドに記載する。
古くから使用される方式のため、ほとんどのWebサーバやWebクライアントが対応しているが、認証情報が暗号化やハッシュ化されないため、通信途上で第三者に覗き見られる危険性がある。
そもそも、
$ echo Z3Vlc3Q6VGFrZTU= | base64 -D guest:Take5
このようにbase64をデコードすることによって、簡単に元の文字列を判定することが出来る。
よって、Basic認証を使う時は、それが許される程度のセキュリティ強度でいいのか?SSL(Secure Socket Layer)やTLS(Transport Layer Security)を使ってHTTPS(HTTP over Secure Socket Layer)通信し、通信路上で暗号化するか?を検討する必要がある。
Digest認証
Digest認証は、Basic認証よりもセキュアな認証方式である。 あるメッセージに対して、ハッシュ関数を適用した結果のハッシュ値を使って認証を行う。 ハッシュ関数とは、データからそのデータを代表する数値を求める関数のことで、ハッシュ関数を使って得られた値のことをハッシュ値と呼ぶ。
Basic認証では、
DELETE /test HTTP/1.1 Host: example.jp Authorizaition: Basic dXNlcjpwYXNzd29yZA==
このようなリクエストで送信していたが、Digest認証では、
HTTP/1.1 401 Unauthorized WWW-Authenticate: Digest realm="Example.jp", nonce="1ac421d9e0a4k7q982z966p903372922", qop="auth", opaque="92eb5ffee6ae2fec3ad71c777531578f"
このようにより複雑なレスポンスが返ってくる。
このWWW-Authenticateの値のことをチャレンジと言う。 クライアントはまず認証なしで、リクエストを送信した上で、チャレンジを使って次回のリクエストを組み直す。
nonce
はnumber used onceの略で、リクエストごとに変化する文字列である。
nonceの値は、サーバの実装に依存しているが、基本的には、タイムスタンプやサーバだけが知り得るパスワードから生成する。
qop
はquality of protectionの略で、auth
かauth-init
を指定して使用する。
qopの値はクライアントが送信するダイジェストの作成方法に影響を与える。
authの場合、メソッドとURIからダイジェストを作成する。
auth-initの場合、メソッドとURIに加えてメッセージボディーも利用する。
これにより、POSTやPUTでボディを送信するときは、auth-initを使うとメッセージ全体が改ざんされないことを保証することが出来る。
opaque
は、クライアントには不透明(推測できない)文字列で、同じURI空間へのリクエストえは共通してクライアントからサーバに送る。
これらを以下のような流れで実行する。
- ユーザ名、realm、パスワードを「:」で連結し、MDS(Message Digest Algorithm)ハッシュ値を求める
- メソッドとURIのパスを「:」で連結し、MDSハッシュ値を求める
- 1の値、サーバから得たnonce、クライアントがnonceを送った回数(cnonce)、qopの値2の値を「:」で連結し、MDSハッシュ値を求める
サーバ上にパスワードのハッシュ値を保管し、そのハッシュ値を元に認証を行うため、パスワードそのものをサーバに預けなくて良くなる点から、セキュリティリスクを下げることが出来る。
Basic認証の場合は、同じURI空間のリソースであれば、クライアントは一度認証してしまえば、2回目以降は自動的にユーザ名とパスワードを送れた。しかし、Digest認証では、サーバからのnonceがなければクライアントが側でダイジェスト計算されないため、一度401 Unauthorizedレスポンスを返さなければならない。
また、パスワードを暗号化するだけなので、メッセージを暗号化したい場合は、Basic認証同様HTTPSを利用する方法が考えられる。
さらに、ApacheなどのWebサーバでは、Digest認証がオプション扱いでサポートしておらず、自前で実装しなければならないといった状況が考えられる。
キャシュ
概要
キャッシュとは、サーバから取得したリソースをローカルストレージ(HDDなど)に蓄積し、再利用する手法のことである。 ローカルストレージにキャッシュしたデータそのものをキャッシュと呼ぶも事もある。 クライアントが蓄積したキャッシュは、キャッシュが有効な間、再度そのリソースにアクセスしようとした時に、再利用する。
キャッシュ用ヘッダ
クライアントが、サーバから取得したリソースがキャッシュ可能かどうか? そのリソースのキャッシュに関するメタデータが入るヘッダについて説明する。
Pragma
Pragmaヘッダに指定できる値は、公式にはno-cache
のみ。
この値はリソースをキャッシュしてはならないことを示す。
クライアントは、次回リソースにアクセスする時、必ず再度サーバにアクセスしなければならない。
Expries
Exouresヘッダはキャッシュの有効期限を示す。 指定できる値には、日時をGMTのみである。 リソースを変更することがない場合、永久にキャッシュ可能であることを示したくないが、そのような場合でも、Expriesには、最長で、約1年後の値を入れることが推奨されている。
Cache-Control
HTTP1.1から導入されたヘッダ。 PragmaもExpiresもどちらも、Cache-Controlで代用出来る。
Pragma: no-cache Cache-Control: no-cache
これら2つは同様の意味として使える。
また、有効期限の書き方として、相対時間(あと○○秒有効) といった設定が出来るようになった。
Cache-Control: max-age: 86400
この他にも、様々な細かい設定が行うことが出来る。 詳細については、RFC 2616を参照。
使い分け
以上の3種類の使い分けについては、次の3つの方針がある。
- キャッシュさせない場合は、PragmaとCache-Controlのno-cacheを同時に指定する
- キャッシュの有効期限が明確に決まっている場合は、Expiresを指定する
- キャッシュの有効期限を相対的に指定したい場合は、Cache-Controlのmax-ageで相対時間を指定する
条件付きGET
クライアントがExpiresやCache-Controlヘッダを検証した結果、ローカルキャッシュをそのまま再利用出来ない時でも、条件付きGETを行えば再利用出来る可能性がある。 仕組みとしては、変更されているかを調べる項目をリクエストヘッダに送って、そのレスポンスからそのまま使えるかどうかを検証する。
If-Modified-Since
まず、リクエストの例は次のようになる。
GET /test HTTP1.1 Host: example.jp If-Modified-Since: Thu, 11 May 2010 03:34:00 GMT
これはローカルキャッシュの更新日時が2010年5月11日3時34分ちょうどであることを示している。 これに対して、サーバはこれ以降変更がない場合、以下のレスポンスを返す。
HTTP/1.1 304 Not Modified Content-Type: application/xhtml+xml; charset=utf-8 Last-Modified: Thu, 11 May 2010 03:34:00 GMT
304 Not Modifiedは条件付きGETへのレスポンスで、リソースが変更されていないことを示す。 これにより、レスポンスにボディを含まないため、ネットワーク帯域を節約出来るメリットがある。
If-None-Match
これも、リクエストの例をベースに説明する。
GET /test2 HTTP1.1 Host: example.jp If-None-Match: ab3322028
HTTP/1.1 304 Not Modified Content-Type: application/xhtml+xml; charset=utf-8 ETag: ab3322028
If-Modified-Sinceヘッダによく似ているが、一番の違いはETagというヘッダの値を更新の判定に使用している点である。 ETagはリソースが更新されるたびに新しい値に変わる文字列であり、特に文字列的な意味はない。 このETagはリソースに紐付けているため、たとえETagの文字列が同じでも違うリソース同士では意味が無い。
ETagの生成方法は静的ファイルと動的ページでは異なる。
静的ファイルの場合
Apacheのデフォルトでは、静的ファイルのETagの値はinode番号、ファイルサイズ、更新日時から自動で計算してくれる。 ただし、inode番号は、同一内容のファイルでもファイルシステムが異なれば別の値となる。 例えば、サーバを分散されている時に注意すべきである。 そのため、ファイルサイズと更新日時のみでETagの値を計算させるようにする。
動的ページの場合 ApacheなどのWebサーバは動的に生成されるHTMLやフィードなどは自動的にETagを計算してくれない。 そのため、Webアプリケーション側でETagの値を計算する必要がある。 一般的には、リソースのメタデータ(更新日時、サイズなど)から作成する方法や、リソースの更新カウ
使い分け
それぞれを使い分けるための方針は次のようになる。
- Last-Modifiedヘッダしか分からない場合はIf-Modified-Since
- サーバがETagヘッダを出している場合にはIf-None-Match
- 時計を持っていないサーバに対してはIf-None-Match
- ミリ単位で変更される可能性のあるリソースにはIf-None-Match
持続的接続
HTTP1.1での新機能がこの持続的接続(Persistent Connection)
HTTP1.0までは、サーバがレスポンスを返すたびにTCPコネクションを切断していた。
これを解決するために、Keep-Alive
ヘッダを利用して、まとめて接続し続ける手法が開発された。
これにより、クライアントはレスポンスを待たずに、同じサーバにリクエストを送信することが出来る。
HTTP1.1では、このKeep-Alive
が標準化されている。
コネクションを切断したい場合は、リクエストのConnection
ヘッダにclose
という値を指定すれば良い。
Webを支える技術を研修で読んでる まとめ4
この記事について
技術研修で読み進めているWebを支える技術について、各章のまとめを順次上げていく。
ステータスコードとは
概要
WebサービスでもWebAPIでもリクエストに対するレスポンスの内容を概略的に表したものがステータスコードである。 これらを正しく使うことは、WebAPIを作成する上でのマナーである。 例えば、エラーを表すコードを返さなければならないのに、成功のコードを返してしまったら、受け取った側はそれを正しいものとして認識してしまう。 つまり、ステータスコードが正しく守られていない場合は、専用のクライアントを実装しなければならず、色々なクライアントで使用出来るというWebAPIの利点を活かすことも出来ない。 そのため、誤用することなく、正しい理解をすることが求められる。
Webを支える技術を研修で読んでる まとめ3 - pokotyamu的書きなぐり日記で述べた、レスポンスメッセージの1行目にあるのが、ステータスラインである。
おさらいすると、ステータスラインは、プロトコルバージョン、ステータスコード、テキストフレーズから成る。
例えば
HTTP/1.1 200 OK
といった形のステータスラインがあった場合。
200
がステータスコードである。
ステータスコードは3桁の数字であり、先頭の数字によって5つに分類することが出来る。
ステータスコード | 意味 |
---|---|
1xx | 処理中 |
2xx | 成功 |
3xx | リダイレクト |
4xx | クライアントエラー |
5xx | サーバエラー |
この5つに分けられている理由としては、次の3つが挙げられる。
- どのようなレスポンスであったかの概要を理解することができる
- クライアントとサーバの結びつきを緩やかにすることができ、サーバのバージョンアップやクライアントの置き換えが行いやすくなる
- ステータスコードが新たに追加された場合でも、先頭の数字さえ分かればクライアント側で最低限の処理を行うことができる
以降では、5つの分類それぞれの概要と代表的なものについて説明する。 基本的にRFC2616の原文リンクの和訳と補足の形ですすめる。
1xx
概要
1xx系は、処理が継続していることを示す。 クライアントはそのままリクエストを継続するか、サーバの支持にしたがってプロトコルをアップデートして再送信する。 実際に見かける場は、ほとんどないため、今回は割愛する。
2xx
概要
何かのリクエストが成功したことを示す。
200 OK
リクエストが問題なく受理されて、要求に従ったレスポンスが返る。 ブラウザでページが読み込まれて、表示された時に使用されることから、一番遭遇頻度が高いステータスコードといえる。
201 Created
リクエストが完了し、新たに作成されたデータのURIが返る。 新たに作成されたURIの情報はレスポンスヘッダのLocationで示される。 ※ただし、PUTで作成した場合は、Locationは返らない さらにレスポンスで返されるリソースのタイプはContent-Typeで示される。
この生成処理は、リクエストを返す前には終了していなければならず、もし直ぐに返せない場合は、202 Accepted
を返す。
3xx
概要
他のリソースへのリダイレクトを示す。 クライアントはこのステータスコードを受け取った時、レスポンスメッセージのLocationヘッダを見て新しいリソースへ接続する。
301 Moved Permanently
リクエストで指定したリソースが新しいURIに移動したことを示す。
その時のロケーションはレスポンスヘッダ内のLocationで示される。
もし、301のステータスコードをGET
,HEAD
メソッド以外で受け取ったユーザエージェントは、条件の変更などが発生する場合があるため、ユーザが確認出来るまで、自動的にリダイレクトの要求を受け取るべきではない。
302 Found
リクエストで指定されたURLが一時的に存在せず、別のURLに仮の移転をしているので、移動先のURLに転送したことを示す。
302のステータスコードも301と同様にGET
,HEAD
メソッド以外で受け取ったユーザエージェントは、条件の変更などが発生する場合があるため、ユーザが確認出来るまで、自動的にリダイレクトの要求を受け取るべきではない。
303 See Other
主にPOST後のリダイレクトで用いられる。 フォームからPOSTした後にリダイレクトしてTOPページに戻す場合が考えられる。 最初の処理では、POSTでリクエストしたが、ブラウザはリダイレクト先にはGETを使う。
307 Temporary Redirect
HTTP1.1で追加され、本来の302が持つべきだった内容を再定義している。よって今後の設計においては、302ではなく307を使うことが推奨される。 最初のURLでは実際の処理は行わず、リダイレクト先に改めてリクエストを出し直して欲しい時に使う。 つまり、最初のリクエストがPOSTだった場合、ブラウザはリダイレクト先にもPOSTを使う。 基本的な処理自体は302と変わらないが、元々リクエストに使った動詞をそのまま使って、変更先のURIにリクエストして欲しい場合は307を使うべきである。
参考:HTTPステータスコード – 302 Foundと303 See Otherと307 Temporary Redirectの違いについて
301と307(302)の違い
どちらも、URIの移動を示すステータスコードである。 ユーザ目線からしても、どちらもページが移動する挙動のため意識する必要はない。 しかし、 検索エンジンからすると以下のように挙動が変わる。
- 301の場合は、URLが移転先のものになる
- サイトのリニューアルでURLが変更になった場合
- 307(302)の場合は、URLが元のURLのものになる
- サーバーエラーが発生したときにエラーページへリダイレクトする場合
サイトのURIを変更する時は、これらの違いを意識する設計が求められる。 参考:301リダイレクトと302リダイレクトは離婚と不倫 – SEO例え話
4xx
概要
クライアントエラーを示す。 原因はクライアント側のリクエストにある。 エラーを解消しない限り正常な結果が得られないので、同じリクエストをそのまま再送信することは出来ない。
400 Bad Request
リクエストの文章が間違っている時に発生する。 クライアントは、再度修正して送り返す必要がある。
401 Unauthorized
適切な認証情報を与えずにリクエストを行った時に発生する。
レスポンスのWWW-Authenticate
ヘッダで、クライアントに対して認証方式を伝える。
403 Forbidden
リクエスト自体の処理は受け付けたが、権限がないために実行出来ない時発生する。 ファイルの閲覧や、外部サイトからのアクセスを禁止しているページで発生する。 解消するためには、サーバ側の設定を調整するしかない。
404 Not Found
指定したリソースが存在しない場合に発生する。 既に削除されてしまっていた場合や、URLの入力ミスなどの時に起こる。
403などで外部サイトからのアクセスを禁止している時に、要求が拒否された理由を正確に明らかにしたくない場合や、他の応答が適用されない場合、404が使用されます。
5xx
概要
サーバエラーを示す。 原因はサーバ側にある。 サーバ側の原因が解決すれば、同一のリクエストを再送信して正常な結果が得られる可能性がある。
500 Internal Server Error
サーバ側に何らかの異常が生じていて、正しいレスポンスが返せない時に発生する。 レスポンスボディには、異常の原因が入る。
503 Service Unavailable
サーバがメンテナンスや高負荷に耐え切れずサービスを提供していない時に発生する。 ツイッターのクジラが出たなどが有名どころ。
エラー処理
4xx系と5xx系は、どちらもエラーを表現している。 エラーコードはHTTP仕様が規定しているが、ボディーにどんなメッセージを入れるかは規定していないので、そのページが人間用なのかプログラム用なのかで分けてエラーメッセージを返すとよい。
まとめ
今回のステータスコードを一覧にまとめる。
ステータスコード | 補足文章 | 概略 |
---|---|---|
200 | OK | リクエストが問題なく受理されて、 要求に合わせたレスポンスが返る |
201 | Created | データの作成が行われ、新たに作成されたデータのURIが返る |
301 | Moved Permanently | リクエストで指定したリソースが 新しいURIに移動したことを示す |
302 | Found | リクエストで指定されたURLが一時的に存在せず、 別のURLに仮の移転をしているので、 移動先のURLに転送したことを示す |
303 | See Othoer | 主にPOST後のリダイレクトで用いられる |
307 | Temporary Redirect | 基本302と同じ。 元々リクエストに使った動詞をそのまま使って、 変更先のURIにリクエストして欲しい場合に使用 |
400 | Bad Request | リクエストの文章が間違っている時に発生する |
401 | Unauthorized | 適切な認証情報を与えずにリクエストを行った時に発生する |
403 | Forbidden | リクエスト自体の処理は受け付けたが、 権限がないために実行出来ない時発生する |
404 | Not Found | 指定したリソースが存在しない場合に発生する |
500 | Internal Server Error | サーバ側に何らかの異常が生じていて、 正しいレスポンスが返せない時に発生する |
503 | Service Unavailable | サーバがメンテナンス中や高負荷に耐え切れず サービスを提供していない時に発生する |
Webを支える技術を研修で読んでる まとめ3
この記事について
技術研修で読み進めているWebを支える技術について、各章のまとめを順次上げていく。 前 pokotyamu.hatenablog.com
次
HTTPメソッドの概要
HTTPメソッドには9つの種類がある。
メソッド | 意味 |
---|---|
GET | リソースの取得 |
POST | 子リソースの作成、リソースへのデータの追加、その他処理 |
PUT | リソースの更新、リソースの作成 |
PATCH | リソースの一部更新 |
DELETE | リソースの削除 |
HEAD | リソースのヘッド(メタデータ)の取得 |
OPTION | リソースがサポートしているメソッドの取得 |
TRACE | 自分宛てにリクエスト・メッセージを返す(ループバック)試験 |
CONNECT | プロキシ動作のトンネル接続への変更 |
以降、各メソッドについて見ていく。 また、ステータスコードについては、次の第8章で述べる。 今回説明中で使用するステータスコードは、あくまで実装の一例である。そのため、実装のやり方によっては変化することがある。
各ヘッダの確認方法はGoogle Chromeの場合 以下の参考リンクのレスポンスヘッダのコピーを参照 参考:coliss.com - Chrome デベロッパーツールの使い方: プロのように華麗に使いこなすための20のテクニック
GETメソッド
GETでは、指定したURIの情報を取得する。 Webページの取得、画像の取得、映像の取得、フィードの取得など、実際にブラウザを利用している時に一番使われるメソッドがGETメソッドである。
GET / HTTP/1.1 Host: www.hottomotto.com
HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Connection: keep-alive Date: Tue, 26 Apr 2016 03:27:37 GMT Server: Apache Vary: Accept-Encoding X-IIJ-Cache: MISS Transfer-Encoding: chunked <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- 途中略 --> </body> </html>
レスポンス例のレスポンスボディー内に、指定したリクエストのhtmlの情報が返されている。 これを読み込んでWebブラウザ上で表示している。
POSTメソッド
POSTメソッドでは3つの役割が存在する。
子リソースの作成
ブログページを親とした時に、ブログ記事が子リソースに当たる。 つまり、ブログ記事の投稿がこの子リソースの作成に当たる。
POST /list HTTP/1.1 Host: example.jp Content-Type: text/plain; charset=utf-8 こんにちは!
HTTP/1.1 201 Created Content-Type: text/plain; charset=utf-8 Location http://example.jp/list/item5 こんにちは!
201 Created
というステータスコードが返ってきたが、これは正常にリソースの作成が出来たことを示す。
Locationヘッダにその新しいリソースのURIが入っている。
リソースへのデータの追加
ログリソースの追加などがこれに当たる。
POST /log HTTP/1.1 Host: example.jp 2016-04-25T10:13:00Z, GET /log, 200
HTTP/1.1 200 OK
ここではPOSTのレスポンスとして、200
が返ってきたが、これは、リソースの作成ではなく、データの追加を示す。
POSTがデータ作成を意味するか、またはデータ追加を意味するかは実装に依存するため、WebAPIの仕様書などを調べる必要がある。
他のメソッドでは対応出来ない処理
URIの長さにはブラウザの実装上2000文字以内などの制約が入る場面がある。 そのような長いキーワードの場合、URIのクエリにキーワードを入れてGETする方法は利用出来ない。 この時に POSTを利用することで、ボディの中にキーワードを格納することが出来る。
POST /search HTTP/1.1 Content-Type: application/x-www-form-urlencoded q=very+long+keyword+hogehogehoge......
PUTメソッド
PUTは2つの役割が存在する。
リソースの更新
先ほどのPOSTの記事作成で作ったリソースの内容を更新する。
PUT /list/item5 HTTP/1.1 Host: example.jp Content-Type: text/plain; charset=utf-8 こんばんは!
HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 こんばんは!
このように、PUTメソッドは、元のリソースを更新するときに使う
リソースの作成
http://example.jp/newitemが存在してないものとする。
POST /newitem HTTP/1.1 Host: example.jp Content-Type: text/plain; charset=utf-8 新しいリソース/newitemの内容
HTTP/1.1 201 Created Content-Type: text/plain; charset=utf-8 新しいリソース/newitemの内容
PUTは存在しないURIへのリクエストのため、サーバはリソースを新しく作成すると解釈し、201 Created
を返す。
/newitemが存在していた場合は、更新として処理される。
PATCHメソッド
2010年のRFC7589で追加された一番新しいメソッド。 リソースの一部更新で使用される。 例えば、ブログ記事のタイトルの更新などに使用される。
PATCH /list/item5 HTTP/1.1 Host: example.jp Content-Type: text/plain; charset=utf-8 ##一部更新内容##
HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 ##一部更新が反映##
このように、基本的には、PUTの子リソースの更新となんら変わらない。 それぞれの違いについては後述する。
Github APIでも採用されているほか、Ruby on Rails v4.0から正式に採用された。
DELETEメソッド
名前の通りリソースの削除を行うメソッド。
DELETE /list/item2 HTTP/1.1 Host: example.jp
HTTP/1.1 200 OK
一般にDELETEのレスポンスはボディーを持たない。
そのため、ステータスコードにボディーがないという意味の204 No Content
が使われる場合がある。
POSTでPUT/DELETEを代用する
今現在、一番よく利用されているのが、GETとPOSTメソッドである。 HTMLのフォームで指定出来るのもこの2つだったが、技術の発展とともに、AjaxのXMLHttpRequestというモジュールを利用することで、任意のメソッドを発行できるようになった。 しかし、XMLHttpRequestをサポートしない携帯電話向けブラウザでは2つのメソッドしか利用出来ない。 また、プロキシサーバではPUTによって勝手にサーバーに関する情報をクライアントに追加させたり置き換えさせたりするため、セキュリティの問題で2つのメソッド以外のアクセスを制限する場合がある。
このような状況で、サーバにPUTやDELETEを伝えるためには、
- _methodパラメータ
- フォームの隠しパラメータに_methodというパラメータを入れる
- その中に本来送りたかったメソッドの名前を入れる
- Ruby on Railsが採用している
- X-HTTP-Method-Overrde
HEADメソッド
GETとよく似ていているが、GETはリソースを取得、HEADはリソースのヘッダ(メタデータ)のみを取得するメソッド。
HEAD /list/item1 HTTP/1.1 Host: example.jp
HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8
先述した通り、ヘッダのみ返すため、HEADへのレスポンスにはボディーを含まない。 利用用途としては、ネットワークの帯域を節約しつつ、リソースの大きさや、更新日時を調べるために使う。
OPTIONSメソッド
OPTIONSは、そのリソースがサポートしているメソッドの一覧を返す。
OPTIONS /list HTTP/1.1 Host: example.jp
HTTP/1.1 200 OK Allow: GET, HEAD, POST
OPTIONS /list/item1 HTTP/1.1 Host: example.jp
HTTP/1.1 200 OK Allow: GET, HEAD, PUT,DELETE
OPTIONS自体は、Allowヘッダには含めない。 また、OPTIONSメソッドは開発者が独自で実装しなければならない。
主要ではないHTTPメソッド
今まで説明した、7つのメソッドが主にHTTPメソッドとしては使われやすい。 ここからは、少し使用頻度の低い2つのメソッドについて説明していく。
TRACEメソッド
TRACEは、HTTPリクエストを「オウム返しに」HTTPレスポンスとして返す。
ただし、注意すべき点として、リクエストをそのまま返すため、レスポンスの中にCookieヘッダ
やAuthorizationヘッダ
も含まれてしまう。
そのため、Cross-Site Tracing(XST)攻撃に利用された。
XST攻撃とは、XSS^1とTRACEメソッドを組み合わせた攻撃手法である。
以下、徳丸浩の日記 - 実はそんなに怖くないTRACEメソッドから引用
XSS単独では、XSSによりJavaScript等が動いているブラウザ上のレスポンス(ヘッダ及びボディ)は取得出来ますが、リクエストヘッダを取得することはできません。このため通常は、HttpOnly属性の指定されたCookieや、Authorizationヘッダ(Basic認証のIDとパスワード)を取得することはできません。 しかし、TRACEメソッドを実行すると、先に見たようにリクエストヘッダがそのままレスポンスとして返るので、XSS単独ではとることのできないHttpOnly属性の指定されたCookieや、Authorizationヘッダを盗み出すことができます。これがXST攻撃です。とくに、BASIC認証のIDとパスワードを盗むことができると、長期にわたって不正にログインすることができてしまうため、XSSの影響が大きくなります。
CONNECTメソッド
RFC 2817の定義によると
A CONNECT method requests that a proxy establish a tunnel connection on its behalf. The Request-URI portion of the Request-Line is always an 'authority' as defined by URI Generic Syntax [2], which is to say the host name and port number destination of the requested connection separated by a colon:
```レスポンス例 CONNECT server.example.com:80 HTTP/1.1 Host: server.example.com:80
日本語に軽く訳すと、 「CONNECTは、proxyとのトンネル接続を作るために使われる。リクエストURIの中にhostme名、ポート番号、リクエスト元の情報がコロン区切りで記述される。これらは、URIの一般的なシンタックスである。」
べき等性と安全性
べき等とは「ある操作を何回行っても結果は同じという考え方」である。 数学の絶対値、0の乗算(3 * 0 = 0)などがあげられる。
また、安全性とは「操作対象のリソースの状態を変化させないこと」を意味している。
これらを主要メソッドであるGET、POST、PUT、PATCH、DELETE、HEADに当てはめると次のような図に分類出来る
○ | 安全性あり | 安全性なし |
---|---|---|
べき等 | GET、HEAD | PUT、DELETE |
べき等でない | POST,PATCH |
GETとHEADは、値を取ってくるだけなのでべき等かつ安全なのは自明である。 PUTとDELETEは、値を更新や作成、削除する点から変化を与えるため安全性はないが、何度やっても値は同じなのでべき等性はある。 POSTは、リクエストの結果次第で何が起こるか分からないためべき等性はなし。更に、リソースの状態に変化も与えるため安全性もなし。 POSTの例としては、通販サイトでのブラウザの戻るボタンを押してしまった時に、2重注文のような問題が発生する可能性を示している。 PATCHは、更新の時に、べき等でなく、安全性もない更新であると定義されている。
POSTとPUTとPATCHの使い分け
POSTとPUT
どちらも新しいリソースの作成を行えるが、それぞれの使い分ける指針として、 リソースのURI決定権が挙げられる。
POSTでリソースを作成する場合、URIの決定権は サーバ側にある。 なので、レスポンスヘッダー内にLocationが含まれる。 この動作の例としては、TwitterのようにUTIをサーバーが自動的に作成する場合が挙げられる。
PUTでリソースを作成する場合、 クライアントが決めたURIがそのままサーバ側で使用される。 なので、レスポンスヘッダー内でLocationが含まれていない。 この動作の例としては、Wikiのようにクライアントが決めたタイトルがそのままURIになるものが挙げられる。
PUTとPATCH
Ruby on Rails(以下Rails)の導入された経緯から、この2つのメソッドの違いを考える。
元々Railsでは、レコードの更新に対して、PUTメソッドが使われていた。
Railsで使用するレコードの中にはupdate_at
という更新時間の項目が常に含まれている。これは、ユーザが指定していない時でも作成される。
この時、レコード内の別の項目だけを更新した時にupdate_at
も一緒に更新時間が変わってしまう。つまり、同じ更新を行う時に毎回同じ結果が返るという べき等性が失われている。
そこで、最初からべき等性も安全性もない、PATCHメソッドを用いることで、この誤用を解消した。
このように、PUTとPATCHは基本的に処理内容としては、同じだが、べき等性が必要か否かで選ぶと良い。 参考:Edge Rails - PATCH is the new primary HTTP method for updates
メソッドの誤用
先ほど、べき等性と安全性の対応表を出したが、全てがあの表に当てはまるとは限らない。 そのパターンについて述べる。
なお、これらのパターンは開発者の問題であることが多く、前述した図が基本と考えて良い。 そのため、べき等性や安全性を考慮して、適切なメソッドを適切なタイミングで使用することを心がける。
GETが安全でなくなる場合
GET: /resources/1/delete HTTP/1.1 Host: example.jp
このようにGETで要求しているにもかかわらず、example.jp/resources/1 を削除しようとする時、安全性がなくなる。 これを防ぐためには、GETの発行前後でリソースに変化が入っていないか?を考えると良い。 基本的にGETでは参照しか出来ないはずなので、deleteなどの動詞がURIに入ってる段階で矛盾している。
PUTがべき等でなくなる場合
価格の更新に対して、現在の価格の50%増加させるといったように、今の差分から処理を行う時 毎回結果が変わってくるため、べき等性がなくなる。 このようなときには、PATCHを使うか、「+50%」といった相対的な表現を避けるべきである。
DELETEがべき等でなくなる場合
ソフトウェアの最新バージョンがhttp://example.jp/latest
というエイリアスリソースで管理されている時、このURIに対してDELETEを行うとどうなるか?
もし、エイリアスリソースそのものを削除するという処理の場合、http://example.jp/latest
が削除されるだけなので、べき等性は保たれる。
しかし、エイリアス先のリソース(最新バージョンのリソース)を指していた場合、ver2.0が削除された次の削除はver1.9になるため、べき等性がなくなってしまう。
このようにエイリアスリソースを削除するように設計するのもいいが、このような特殊なリソースについては、更新や削除などの操作が出来ないような設計にするのが求められる。
CRUDな設計
これまで、9つのHTTPメソッドの種類をまとめた。
これらのメソッドのうち、GET、POST、PUT、DELETEは4つでCRUD
という性質を満たす。
CRUDとは、
- Create:作成、生成
- Read:読み取り
- Update:更新
- Delete:削除
の4つの頭文字を取ったものである。
それぞれの対応関係は、以下の図のようになっている。
CRUD名 | 意味 | メソッド |
---|---|---|
Create | 作成 | POST、PUT |
Read | 読み込み | GET |
Update | 更新 | PUT |
Delete | 削除 | Delete |
CRUDな設計の代表例は、railsのscaffoldした雛形Webアプリケーションが挙げられる。 参考:TECHSCORE - 4.scaffoldを利用した開発(1)
Webを支える技術を研修で読んでる まとめ2
この記事について
技術研修で読み進めているWebを支える技術について、各章のまとめを順次上げていく。
次
HTTPの概要
HTTPはTCP/IPをベースにしている。 TCP(Transmission Control Protocol) IP(Internet Protocol) 現在のHTTPはバージョン1.1が主流として使われており、10年以上更新されていない。 現代の開発スタイルでは、HTTP1.1を有効に使っていこうという流れになっている。^1 ネットワーク・プロトコルは階層毎にわかれている。
各階層は次のようになっている。
- ネットワークインターフェース層
- 物理的なケーブルやネットワークアダプタに相当する部分
- イーサネット
- インターネット層
- IPを使ってパケット単位でネットワークで実際にやり取りする部分
- この時、最終的にたどり着くかは保証していない
- IP
- IPを使ってパケット単位でネットワークで実際にやり取りする部分
- トランスポート層
- アプリケーション層
階層にすることの特徴は
- 抽象度別に分けることが出来る
- ネットワークインターフェース層のほうが抽象度が低い
- 各階層の実装が独立している
- 下位層の実装に依存しない
- 障害発生時などの問題を各層毎に区切ることが出来る
HTTPの仕組みについて
HTTPはアーキテクチャスタイルに クライアント/サーバ を採用している。 クライアント(Webブラウザ)が情報を提供するサーバ(Webサーバ)に接続し、各種リクエストを出してレスポンスを受け取る。 このようなプロトコルを リクエスト/レスポンス型(Request-Response Style) と呼ぶ。
クライアント/サーバそれぞれの役割
クライアントでは、リクエストの送信から受信する際、次のことを行う。
- リクエストメッセージの構築
- リクエストメッセージの送信
- (レスポンスが返るまで待機)
- レスポンスメッセージの受信
- レスポンスメッセージの解析
- クライアントの目的を達成するために必要な処理
次に、サーバでは次のことを行う
- (リクエストの待機)
- リクエストメッセージの受信
- リクエストメッセージの解析
- 適切なアプリケーション・プログラムへの処理の委譲
- DBから最新記事を取得処理
- 広告へのリンク作成処理
- アプリケーション・プログラムから結果を取得
- レスポンスメッセージの構築
- レスポンスメッセージの送信
HTTPメッセージ
先述した、リクエストメッセージとレスポンスメッセージはまとめて、 HTTPメッセージ と呼ぶ。
リクエストメッセージの構造
リクエストメッセージの構造は以下の図のようになっている。
リクエスト行のURIには、http://example.jp:8080/search?q=test&debug=true#n10
のようなURIフラグメントは、リクエストメッセージには含めない。この場合のリクエスト行は、URIフラグメントを除いた、パス以降の文字列が入る。具体的には/search?q=test&debug=true
が入る。
また、リクエストURIは基本絶対URIでも相対URIでも使用出来る。^2 しかし、プロキシへのリクエストの場合必ず 絶対URI となる。
レスポンスメッセージの構造
レスポンスメッセージの構造は以下のずのようになっている。
参考:ネットワークエンジニアとして TCP/IP - HTTP
HTTPのステートレス性
HTTPはステートレスなプロトコルとして設計されている。 これは、サーバがアプリケーション状態を保存しないということである。
アプリケーション状態とは?
アプリケーション状態は、別名セッション状態とも言う。 システムにログインしてから、ログアウトするまでの一連の操作間の状態をアプリケーション状態と呼ぶ。
もしステートフルなプロトコルだと、アプリケーション毎のやり取りをサーバが記憶する必要がある。 反対にステートレスなプロトコルだと、アプリケーション自身でやり取りを全て記憶する必要がある。
それぞれの概要は次のようになる。
- やり取りについて
- ステートフル:簡潔(サーバが記憶しているから)である。
- ステートレス:冗長(今までの状態を話す必要があるから)である。
- 利点
- ステートフル:送信するデータ量が少なくて済む。
- ステートレス:クライアント数が増えた際にシステムをスケールさせるのが楽になる。
- 欠点
- ステートフル:クライアント数が増えると、サーバが記憶しなければならないデータ量が増えるため負担が増える。
- ステートレス:送信データ量が増える。認証など、サーバに負担がかかる処理を繰り返す。通信エラーの際にリクエストが処理出来ているか分からない。
Webを支える技術を研修で読んでる まとめ1
輪講形式で読んでいて、気になった点をまとめておく
第1部:Webの概要
- RPC
- 分散システムを実現するための技術の1つ
- 分散システムの流れが来たが、複雑さの問題から発展しなかった
- Webはシンプルな単方向リンクだけを持つものとして開発
- SOAP
- メッセージ転送の方法だけを定めたプロトコル
- 標準化戦争勃発
- REST
- リソース
- RESTなアーキテクチャのために
- クライアント/サーバ
- ユーザインターフェースと処理を分離する
- ステートレスサーバ
- クライアントのアプリケーション状態をサーバで管理しない
- ステートフルな場合、Cookieを使ったセッション管理をしている
- REST的には間違い
- キャッシュ
- 一度取得したリソースをクライアント側で使い回す
- 効率化はできるが、情報の信頼性が下がる
- 一度取得したリソースをクライアント側で使い回す
- 統一インターフェース
- URIで指し示したリソースに対する操作を統一した限定的なインターフェースで行う
- 階層化システム
- サーバとクライアントの間にロードバランサを設置して負荷分散を行う
- コードオンデマンド
- ブラウザ以外にクライアント側を拡張出来る
- JSやFlashなど
- プログラムをクライアントにダウンロードして実行する
- ブラウザ以外にクライアント側を拡張出来る
- クライアント/サーバ
第2部:URI
- URIの仕様
- railsのrouteファイルなどに関わってくるから、ここから大事!
- URIスキーム
http://hogehoge.com
http
の部分がURIスキーム
- URIフラグメント
hogehoge/member#user1
- ページ内の#以下の文字列の要素を示す
- URIの設計
第3部:HTTP(Hypertext Transfer Protocol)
アメリカの中学生を対象にワークショップやってみて感じた日本との違い
留学6週目の最終週の記録です。
今週はSunnyvaleの中学校でロボットでサッカーを行うロボット教室をやりました。
ロボットはDAISEN社製のTJ3Bという既成品を使用して
それの組み立て→プログラム作成という流れで行いました。daisen-netstore.com
ロボットはC言語を用いたプログラムに従って動くのですが、
実際に子供たちが作成する時はC-styleというビジュアルプログラミングソフトを使用して行います。*1
今回はその中で私が感じた日本の子供たちとの違いについてまとめていきたいと思います。
1.子供の自発性に任せる
【日本の場合】
進研ゼミの告知の仕方が日本の教育の全てを物語ってるのではないでしょうか?
「この夏休みで短所を長所に変えよう!!!」
つまりは、日本の教育では、短所をなるべく消して平均的に取れるように指導を進めていく風潮が強いということです。
この教育方針には、
メリット ・クラス全体が同じ進捗で進めやすい ・なんでもそれなりにこなせる人間を増やせる デメリット ・尖った人間が育ちにくい ・一度ついていけなくなると落ちこぼれる可能性が高い
というメリット・デメリットがあると考えました。
高校生のときに、中学後半の英語や数学を授業レベルでやり直すのは難しいのは容易に想像が出来るかと思います。
自分からというより、受動的にしか受けようがないというのが今の教育の限界なのかもしれません。
そして、平均的に出来るだろうという気持ちから、
失敗するのが怖いという思考になってしまうのかなと思います。
【アメリカの場合】
ロボット教室をやってて思ったのは
自分達が用意したスライドの2歩ぐらい先を勝手に自分で考えて進めていたことです。
最後には、お互いに分からないとこを教え合って授業と言っても後ろからサポートしてあげるだけ、という時間が多かったです。
こっちの子供たちの好奇心は、実際に形にするまで止まりません。
トライ・アンド・エラーで勉強できることを彼らは知っているのです。
では、もしこの時日本式に
「みんなで一緒に進めるからちょっと待ってて。」
と言って彼らのやる気を止めたらどうなるか?
答えは、全く関係ないことをやり始めて、その後ロボットには目もくれなくなります。
それだけこっちの子供は自発的に興味を持ったものには全力で突き進みますが、
上から押し付けたり指示すると興味をモチベーションが下がってしまう文化が、ここにはあると感じました。
さらにもう1つ
アメリカの学校では、単位毎に飛び級が認められています。
やってることが幼稚なら先に進む。
分からないで進むなら、理解するまで止まる。
このような教育を受けることが出来ます。
2.何事にもアグレッシブ
【日本の場合】
日本の授業風景を思い出してください。
先生「質問ある人ー?」 生徒「・・・・・・」 先生「はい、次進みますー」
これは、よくある日本の教室の光景だと思います。
全員の前で質問することに対して恥ずかしさや、授業を止めてしまうのでは?という申し訳無さ
そんな空気感からなかなか手を挙げるのは簡単ではないことは、私も当時感じていました。
いわゆる、日本人はシャイだねってやつですね。
【アメリカの場合】
もし、自分の分からない点が出てきたら
「これはどうなってるの?」
「どうして動かないの?」
こんな質問をひたすら連呼してきます。
この連呼するというのがポイントで、自分が分からないポイントは
とことん理解するまで知りたいという欲求が、彼らには働いているように感じました。
だからこそ、自分の理解している範囲内ではドンドン進めていきたいのでしょう。
特に今回の授業では、自分がプログラムを書く→ロボットが実際に動くことで確認出来る。
このサイクルで開発を進めていけたので、早くもっと高度なことがしたいという気持ちに駆られたように感じます。
3.意見の伝え方と納得の仕方
【日本の場合】
小学校、中学校で何か決め事をするときに一番使われるもの
そう「多数決」ですね。
多くの日本人が多数決で決まったなら、自分が納得せずとも受け入れてしまう
そんな経験はありませんか?
現在の大人が受けた教育で、多くの人が議論を行う経験が少なかったように感じます。
自分の意見を主張するより周りに合わせる。
5段階評価アンケート形式で真ん中が多かったりする。
自分の意見を意地でもねじ込もうとする方法が確立されてないため
どうしても感情的に突き進む連中が、最近よく国会前で騒いでいたりするのかなと。
教育されてないから、あんな滑稽な演説しか出来ないのだろうとまとめながら感じました。
デモ自体やることはいいのですが、もう少しロジカルに演説すればいいのに、
「戦争法案!」「徴兵制にはさせない!」「安倍下ろし!」
これしか言わないデモに何の意味があるのか。
【アメリカの場合】
ロボット教室の場面でこのようなことがありました。
今回のサッカーの試合では、白い枠からはみ出したら1分間退場扱いというルールがあります。
試合時間は5分なので、そのうちの1分とはかなり大きいペナルティと感じたのでしょう。
1人の子供が「30秒に変更してよ!!!」
これを10回以上審判である私達に訴えてきました。
確かに、彼のロボットは何回も場外に進んでいました。
これに対して「それは出来ない」という回答を私達は繰り返しました。
教室が終わった後の反省で言われたのは
・"Just rule!!”と突っ張る ・なぜ30秒に変更してはダメなのかの理由を伝えてあげる
この2つでした。
まず1つ目は、自分達が試合をしている彼らより圧倒的に上の位置で判断していると伝えてあげることで
変な申請をこれ以上させないという効果があります。
これをしないと、今回のようにナメられて、自分の意見をねじ込めようとしてきます。
そして2つ目は、ロジカルに納得するとそれ以上自分の意見を訴えても無駄だと本人が一番わかっているということからです。
実際、今回1分と設定した理由としては、授業の中で最低限フィールドから出ないようなプログラムを組むようにという指示をしていたので
かなり重いペナルティとなっていました。
それを伝えることが出来れば、彼も納得して試合をすることが出来ただろうなと今になって思っています。
まとめ
以上の3点について最後にまとめると
日本人の教育の場合
・短所を直して全体を平均的にする ・疑問があっても蓋をして進める ・反対の意見を述べることが悪いことという空気感がある
アメリカ人の教育の場合
・長所をひたすら伸ばし続ける ・自分だけでは分からない疑問は即解決する ・自分の意見をロジカルに否定することでのみ納得する
今回は特にアメリカの子供たちのメリットの部分を強調して記事を書いてみました。
もちろん、デメリットも考えたらあると思います。
けど、それはアメリカ社会と日本社会の違いだと思っていて、
アメリカでは個の特徴的な人の集合体で会社が動いている。
日本では、平均的な力でベースとなる底力を上げることで会社が動いている。
まぁ最近は日本でもITベンチャーはアメリカナイズされた考え方を持ってる会社も多いかと思います。
そこで、自分が働く場合は、自分の価値観(スキルセットの揃え方)もアメリカナイズさせる必要があるのかと感じました。
*1:ビジュアルプログラミングといえば、scrachやsmalrubyが有名ですね