新卒が真面目にアジャイル勉強してみた

社内勉強会で、アジャイルについて発表してみたので、こちらにも残しておきます!!!

当日資料はこちら↓↓

やってみた感想

きっかけは、なぜスクラムしているの?

資料の中にも書いていますが、自分が今回アジャイルについて勉強を始めたきっかけは、1番新しくチームメンバーとして入った方の「なぜスクラムしているの?その利点は何?」という発言でした。

実際に開発メンバーとして仕事をしている上で、何も知らない中スクラムを実施していることに違和感があったので、今回社内勉強会という機会を利用して、自分で勉強して、発表することにしました。

結果として、今のチームとしてここは良い点悪い点が言えて、そこから改善案も考えれるようになりました。

新卒が開発手法について口を出す

チームの中でも1番年下になりやすい新卒だからこそ見える世界もあると思います。 ただ、意見を1番いいにくいのも新卒な気がします(経験の問題や会社の風土だからという感じに流される)。

だからこそ、意見を言うための確かな知識を勉強して、経験じゃない根拠を持って話すことが出来れば、雰囲気に押し流されない意見を言えるようになるのではないか?とやってみて感じました。

アジャイル守破離の心構え

「これが正解」「こうやるもの」というわけではなく「何を目的にしていてこういうやり方が進められている」を知るのが「守」かな

これは、発表を終えたあと頂いた弊社 CTO からの感想です。

これも先程述べたように、原理原則を知った上で行動や意見をする必要があるという気づきにつながりました。

勉強会に対するモチベーション

準備期間が長く取れる場合ほど、途中で別のことしたくなったりなどあるかと。

今回はそれ対策で、途中途中で発表内容に使う本のまとめやセミナーのまとめを社内 Qiita やこのブログにまとめることで承認欲求を満たしつつ準備するというので乗り切りましたw

何かしらのリアクションやご意見を頂きつつ勉強することで、自分の見えてない見方や考えを途中の段階でも知れるきっかけになります! これは意外とよかったです。

pokotyamu.hatenablog.com

pokotyamu.hatenablog.com

※内容がネタバレ的になっちゃう系の場合はこそこそ頑張りましょう!

まとめ

スライドメインなので、さらっと終わりますが、今までチームとしてのやり方しかしらず、アジャイルスクラムを研修や独学で知識を付けてない方はぜひ一度勉強することをおすすめします!!!!

LEGOスクラムに参加した!(レゴ編)

この記事なに?

12/14(木) に行われたLEGOスクラムのレポートです!

イベントの詳細についてはこちら↓

waicrew.doorkeeper.jp

座学編はこちら↓

pokotyamu.hatenablog.com

今回は実際のワークでもあるレゴ編です!

ユーザーストーリーを作る

各チームが1つの家族で、家族が希望する街に引っ越すという形でワークが始まりました。

私が担当したのは私立女子校に通う JK の娘↓

f:id:pokotyamu:20161214131920j:plain

要求(ユーザーストーリー)はこのテンプレートにそって書いていきます。

(役割や立場)として、
(機能や性能)が欲しい。
それは(理由や目的)のためだ。

f:id:pokotyamu:20161214135450j:plain

うん!実に最近の JK っぽいですね()

ここでポイントとなるのが、3行目で、3行目の理由や目的を解決するための手段として、2行目があるので、できるだけ3行目を具体的に書くことが大事になってきます!

もちろん、別な手段(2行目)で解決出来ることが開発側からあれば、そちらを提案できるようにしておくのが、顧客にも求められます。

プランニングポーカー

それぞれのユーザーストーリーがまとまったら、プランニングポーカーを使って、見積もりをしていきます。

あくまで絶対評価ではなく、相対評価で、作業の見積もりを行うやり方です。

写真は、10個の都道府県の人口を 1,2, 3, 5, 8 に分けるワークを行っています。 基準として与えられたのが、福岡が5、長野が2という情報だけです。

f:id:pokotyamu:20161214133326j:plain

絶対評価だと、難しいですが、相対評価になることで、見積もりの精度を上げることができます。

ただし、このやり方は声の大きい人の意見が通りやすいので、ファシリテートが大事そうに感じました。

いよいよ LEGO

ここまで終わったら、実際に LEGO を使ってまちづくりです。 今回のスプリントでやることを決める(2分) →作る(7分)→顧客が評価する→振り返り この流れで3スプリント分行いました。

f:id:pokotyamu:20161214143157j:plain

f:id:pokotyamu:20161214165811j:plain

成果

最初は獲得したベロシティは0pt だったのですが、最後は9pt 分獲得することができました。

その要因としては、

  • チームとして、最終成果物の認識を合わせることが大事
  • 作業の分担を決めた
  • 全員で1つの作業に取り掛かった
  • PO に質問を最初にまとめておこなった
  • 時間管理を行った

このような点が考えられます。

2つ目に挙げた作業分担ですが、正直これに関しては、スクラムというやり方的には真っ当ではなかったのですが、3スプリントで成果をだすことを目標にしたので、固定化しました。

もっと期間がながければ、役割を何度かシャッフルして、得意な分野に対して、サインアップしていくやり方が正しい気がします。今回はスキルなどもわからない点が多かったためにこのような形をとりました。

また、最後の時間管理については、あと何分だから、ここは諦めるなどの決定をチームで行ったことで、ミニマムな建造物を作る方にシフトしてたのもベロシティがあがった要因だと思います。

これは、品質の悪いものをとどけるという意味ではなく、成果が0よりは、何かしらの形あるものに対してフィードバックをもらって開発を進めたほうがよいという判断をチームで行ったために、このようになりました。

結果として、アジャイルな開発に沿った形で開発を行えた気がします。

難しかった点

  • 他のチームの PO を捕まえて仕様を確認する必要が度々発生したのですが、やはり PO は忙しいので、個別でいくのではなく、まとめて質問する必要があると感じました
  • 成果物のイメージが固まっていないと、各々の方向に向かって開発を進めてしまって、結果何もできないという未来がまっていた
  • カンバンに対する意識を7分間の中に入れ込むのは少し難しい
    • もっと時間のある期間であれば問題なさそう

感想

2つの記事に分けてまとめていきましたが、率直に参加して良かったと思っています。

体型的に知識を入れることができた点もありますが、実際のワークを通して、アジャイルな考え方が整理された気がします。 また、スクラム開発を行うのであれば、チームメンバーは最低限の知識として、このぐらいは経験じゃなく本や研修として学んでおくほうがよいと感じました。

もうしばらく、スクラムアジャイルについて勉強を深めていきたいと思います!!!! f:id:pokotyamu:20161214170602j:plain

LEGOスクラムに参加した!(座学編)

この記事なに?

12/14(木) に行われたLEGOスクラムのレポートです!

イベントの詳細についてはこちら↓

waicrew.doorkeeper.jp

参加の理由としては、「今のチームでやってる手法がちゃんとアジャイルのレールに乗っているか?」「体系的に一回知識を入れてる一貫として、先輩におすすめされたから」

といった感じでした。

チーム決めでは、スクラムについて詳しい順に並んでくださいということで、まさかのプロジェクトでやってる方が私しかおらず、参加者の中で1番詳しい人となりましたw

この記事では座学で学んだ部分についてまとめます。

ちなみに、メモは会社の slack で垂れ流ししてました。

f:id:pokotyamu:20161215114442p:plain

アジャイル is 何? スクラム is 何?

まずは、なんでもかんでもアジャイルを適用すればいいのか? いわゆる銀の弾丸なのか?という話です。

大前提アジャイルに定義はない!!

あえてあげるとすれば、態度概念

スクラムやカンバンといった方法論を身につけることで、アジャイルが習得されるでいいということです。

では、スクラムとは何なのか?

スクラム=複雑で変化の激しい問題に対応するためのフレームワーク。可能な限り価値の高いプロダクトを生産的かつ創造的に届けるためのもの。

複雑で変化の激しいとはどんな状況なのか?

何を作ればいいか・どうやって作ればいいかが中途半端なものをここでは、複雑(Complex)なものとして定義します。

例えば、夏休みの宿題のようなものは、スクラムに向いていません。

なぜなら、何をするかも、どうやるかも明確で、各教科を1つずつ終わらせていけば全ての作業が完了するようなものだからです。特に変化が発生する要素がないので、別の方法を適用する方がよいらしい。

セミナーの中では WBS*1 に切ることが出来るものということも仰っていました。

また、漠然としすぎていてもそれはそれで問題だそうで、「世界を良くするものを作る」という、何を作ればいいか・どうやって作ればいいかが難しすぎる(Anarchy)な問題に関してもスクラムを適用することはできません。

これを達成するには、デスマーチしかないとのこと。

これらの真ん中の作業の時にスクラムが有効な手段となりうるそうです。

アジャイル開発は、オブジェクト指向開発を人間に当てはめたもの

オブジェクト指向形のプログラミング言語の特徴として、クラスに生えてるメソッドはどのインスタンスでも同じような振る舞いを行うというものがあります。

その考え方をプロダクトマネージメントにも応用しようと考えたのがアジャイルなチームの始まりで

  • 1つ1つのタスクが誰がどの作業をやれる状態となっている
    • アサインではなく、サインアップ
  • 機能横断型なメンバーでチームを構成する

1つ1つのタスクが誰がどの作業をやれる状態となっている

これは、タスクの粒度や共通認識のレベルの話で、全員が同じ規模感や認識を持つことが重要ということです。

そして、1つ1つのタスクに対して、誰かから当てはめられるのではなく、手が空いた人から「これやります!」というのが大事になっています。

確かに、うちのプロジェクトでもサインアップは意識されている気がする

機能横断型

機能横断型とは、自分の領域を絞らずに全部出来る(しようとする)ゼネラリストのような人が集まった集団が求められるということです。

例えば、「自分はバックエンドだけしかするつもりありません」という人より、「デザインもできますし、インフラもできます」というような感じです。

今まで、スクラムは一手法として捉えていたので、オブジェクト指向を人間に当てはめたものという表現は納得感のあるものでした。

一回で完成品を作ろうとするのは無理

半年がかりで、どかっとした機能を作るのではなく、雪だるまのようにちょっとずつやれることを増やしていく考え方でプロジェクトを進めます。

  1. 最小の単位で作ってみる
  2. 製品とプロセスの振り返りを行うこと

特にどのようにこれらを作っていったか?というプロセスまで振り返りができるようにすることで、個人としてではなく、チームとしての成長を狙っています。

座学の中では最高に美味しい焼きそばの作り方というテーマでワークが行われました。

ラグビー型のチームへ

複雑で変化の激しい領域に対応するならば、継続的にちょっとずつ前に進める変化に強いチーム作りを意識しなければならない。

f:id:pokotyamu:20161217134846g:plain

引用:The New New Product Development Game

type A のようなリレー形式のように、引き継ぎ引き継ぎで作業をするのではなく、同じチームで継続的に少しずつ進んでいく type C のようなラグビー型のチームのほうが早く進めることができるという調査。

このラグビー型チームにしていくためには、決まったパターンがあるので一回それに当てはめてみてトライアンドエラーで進めていくことが大事そうに感じました。

基本的に【プロダクトオーナーxスクラムマスターx開発チーム】の構図

ここでいう開発チームは、実際にコードを書く人だけでなく、テスターやデザイナーも含まれるそうです。

そして、プロダクトオーナーは「何を作るかの責任者」であるため、必ずしも技術に長けている必要はない。 顧客からの要求をスキニングしたり、製品の価値として、どこまで求めるかの意思決定を行う。

スクラムマスターは「どうやって作るかの責任者」であるため、そのチームの中で一番技術に長けている人がなるべき。

チーム内で発生したバックログに全く関係のない雑務(例えば会議の調整)もスクラムマスターが行うべきだそうです。

その理由としては、チームとして目標を達成できることが一番なため、個人のスキルを高めるために余裕のある人が「技術的に一番余裕がある人」である点。 また、他の人に目を配る余裕がある点や、何をやっているかが(技術的に)わかる点も1番スキルの高い人がやるべき要因です。

そしてなにより、技術に長けている= Complex な問題を解決する力が強いわけではないということも前提としてあります。

まとめ

ここまで、アジャイルの方法論の一つであるスクラムについて書いてきましたが、最後にまとめると。

  • スクラムは適度に複雑(Complex) な問題を解決する方法で簡単すぎても漠然としすぎてもいけない。
  • なんども繰り返してチームとして問題解決を行える力を付ける
    • そこでは必ずプロダクトとプロセス両方の振り返りを行う

この座学のなかではあまり触れられていなかったのですが、お客さんがアジャイルに積極的かどうか?という点も実際の仕事においてはかなり重要になっていくそうで、お客さんの理解を得る方法については、アジャイルサムライに、確実に動くものを毎週届けることで、少しずつ信頼を得ていくというのが大事という風に書いてありました。

あと、ここや本に書いてあることはあくまでもテンプレートなので、最終的な形は自分たちでカスタマイズして作っていくことが大事になってくるのかなと思いました。

最初から、アジャイルな気持ちで〜と言っても何をすれば?となってしまうので、初めは型にハマって、次第にカスタムしていくというのかな。

特に Web 業界だと、週に1回のリリース頻度だとちょっと遅すぎるので、そこらへんのバランスも必要になってきたりしそうです。

というのが座学の感想です。

後半のレゴ編に続きます

pokotyamu.hatenablog.com

*1:Work Breakdown Structure:作業分解構成図

HHKB を掃除した話 #HHKB20th

この記事はfeedforce Advent Calender 2016 の16日目の記事です!

www.adventar.org

昨日は同じチームの UX デザイナーよーさんが書いてくれました。

medium.com

この人、結局君の名は。何回行ったんだろう...7~8回?


みなさん、そろそろ大掃除の時期ですね!

お部屋のお片づけは順調でしょうか?

私は進捗ゼロです!!!!!!!

そんな私がまず取り掛かる場所。 そうキーボードですね!←

というわけで、今日は、私の愛機の HHKB を掃除した話をお届けします!

そもそも HHKB って?

↑こちらが今使っている Happy Hacking Keyboard Professional 2です。

矢印キーがないのでとても省スペースである点。 ストロークが深く、打鍵するとコトコトという非常に心地よい音がするのが特徴です。

さらに、無刻印にすることにより、集中力が研ぎ澄まされるという効果もあります(個人差あり)

なお、かなり癖が強いため、慣れるまでに時間がかかるのが難点です。

いわば小柄な体系で、最初はツンだけどそれでもアタックし続けることで、やっとデれてくれるような手のかかる女のk...(ry

HHKB の魅力については、こちらの記事がおすすめです!!

www.mikinote.com

そんな HHKB を掃除開始

f:id:pokotyamu:20161210194846j:plain

準備するものとしては、

があれば十分な気がします キートップ抜きは、ヨドバシなど電気屋さんで買うとよいかと!

まずは、汚れを確認。

f:id:pokotyamu:20161210194523j:plain

埃がだいぶ溜まってる....

キートップを外していきましょう!

こんな感じでズバズバ抜いていきます!

抜いたら 無くさないように洗濯ネット に入れましょう!

f:id:pokotyamu:20161210195013j:plain

全部抜き終わった写真がこちら↓

f:id:pokotyamu:20161210200807j:plain

あぁ...きちゃない...

スペースキーの部分にバネがついているので、無くさないように注意です!

キートップを洗う

今回は、普通の中性洗剤を使いました。

f:id:pokotyamu:20161210202931j:plain

それをタオルで拭いて、乾かします!

f:id:pokotyamu:20161210203555j:plain

乾くのを待ってる間に、本体のお掃除

こちらには、どこのご家庭にもある精密ピンセットを使いました!

f:id:pokotyamu:20161210202409j:plain

普通ならエアー缶を買って、風でシャーっとしたほうが早いと思います

いざ!キートップの装着

掃除始める前の僕「無刻印やから、キーの配列考えなくていいから楽勝やんけ〜」

パチパチ....パチパチ....パチパチ....

f:id:pokotyamu:20161210212752j:plain

パチパチ....パチパチ....パチパチ....パチパチ....パチパチ....パチパチ....おわった!!!!!!

f:id:pokotyamu:20161210215216j:plain

以上にて、この記事を....

あれ?いつもと感触が違う???????

f:id:pokotyamu:20161210211947j:plain

( ゚д゚) ・・・ (つд⊂)ゴシゴシ (;゚д゚) ・・・ (つд⊂)ゴシゴシゴシ ( ゚д゚)

微妙に高さが違うんですね()

特に左側2つ(´;ω;`)

f:id:pokotyamu:20161214185255j:plain

この後、違和感あるとこ付けては外しを繰り返して 完成しました!!!

f:id:pokotyamu:20161210215226j:plain

高級なキーボードはちゃんと手の形に合うように、湾曲しているそうなので、列ごとで洗濯ネットに入れとくと良いかも知れません!φ(..)

みなさんも、年越しの大掃除リストにキーボードを加えましょう!!!


明日は、新卒同期の有給消化率ナンバーワン tsub 氏です!!!

追記

会社のはてブコメントから、公式さんが教えてくれなかったことを教えてくれた!!!!!!!

突撃!隣のキーボード - Feedforce Developer Blog

HHKB無刻印洗濯は考えなしにはじめると紹介記事のごとくハマるんですけど、キートップ裏に書いてある記号で何のキーかわかったりします。

2017/11/15 20:52

f:id:pokotyamu:20171116102711j:plain f:id:pokotyamu:20171116102712j:plain

下から A→B→C... って振られている感じみたいです! 数字は横の並び順かな?どっちが1番なんだろうw

あなただけの登山ルートがそこにはある『山頂をめざせ』:ボドゲ紹介

この記事何?

この記事は、 2016年ボドゲ紹介02 Advent Calendarの7日目です。

www.adventar.org

参加を決めてから気づきましたが、ボドゲ紹介01 の7日目は弊社のボドゲ部部長 @kano_e さんが書いていますので、そちらもどうぞ

www.evernote.com

今日紹介するゲームは、お気に入りなサイコロゲー「山頂をめざせ」です!

Gipfelstürmer: AMIGO - Familienspiel

Gipfelstürmer: AMIGO - Familienspiel

まずは簡単にルールから

まずはじめに、1人5匹のヤギとプレートを一枚ずつ持ちます。

このヤギさんを山頂に進めるのがゲームの目的です!

この5匹のヤギを山の麓に並べてゲームスタート! f:id:pokotyamu:20161203221143j:plain

ターンが回ってくると、サイコロを5個振って各看板に書いてある目をクリアーできれば一歩前に進めます。 サイコロは振り直したいものだけキープして、振り直しは2回まで振り直せます。

例えばこの写真は、3と6のツーペアが揃っているので、 f:id:pokotyamu:20161202224817j:plain f:id:pokotyamu:20161202224826j:plain

このツーペアの看板が進めるという感じでズンズンヤギさんを進めていきましょう!

自分のヤギさんを押し上げちゃえ

山頂までのルートにはヤギさんが止まる枠があるのですが、それには上限が決まっています。 小さい枠はみんなで1匹、大きい枠は個人で2匹までです。 じゃあ、それ以上は進めないのか?

f:id:pokotyamu:20161203223344j:plain

ここがこのゲームの醍醐味! 自分のヤギを押し上げちゃう事ができるんです!!

f:id:pokotyamu:20161203223334j:plain

上に行けば行くほど、看板の賽の目が難しくなるので、 このようになるべく道に続けるようにヤギを配置して、上に上に押し上げていくのがこの山頂をめざせの醍醐味です!!

相手を押しのけちゃえ

ゲームの中盤になると進む先に他の人のヤギがいる。。。という状況になります

f:id:pokotyamu:20161202225510j:plain

その場合どうするか。。。。

f:id:pokotyamu:20161203224450j:plain

f:id:pokotyamu:20161202225521j:plain

邪魔な敵は押しのけていくのです!!!

上手くいけば、一番下まで突き落とすことができます!!

終了条件

こうして、ヤギさんを押し上げたり、敵を押しのけたりして、一番先に山頂に2匹のヤギさんを山頂に登らせたら勝ちです!!

f:id:pokotyamu:20161202231405j:plain

あなたは白色ヤギさんや黄色ヤギさんみたいに準備万端に用意する派? [f:id:pokotyamu:20161202231042j:plain

それとも、緑色ヤギさんみたいに5つのぞろ目を気合いで出す派? f:id:pokotyamu:20161202231058j:plain

  • どのルートを進ませるかという戦略
  • 自分の力で出す目をコントロールする力

両方がバランス良く必要な、山頂をめざせいかかでしょうかo(・ω・´o) この日は着々とヤギさん並べてる間に6の5個ゾロ出されて負けましたw

おわりに

毎週水曜 19:30~ 弊社ボドゲ部活動中です! ほぼ毎週ゲストさんもいらっしゃっていますので、お時間ありましたらぜひ湯島まで〜

ff-boardgame.herokuapp.com

明日は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の略で、authauth-initを指定して使用する。 qopの値はクライアントが送信するダイジェストの作成方法に影響を与える。 authの場合、メソッドURIからダイジェストを作成する。 auth-initの場合、メソッドURIに加えてメッセージボディーも利用する。 これにより、POSTやPUTでボディを送信するときは、auth-initを使うとメッセージ全体が改ざんされないことを保証することが出来る。

opaqueは、クライアントには不透明(推測できない)文字列で、同じURI空間へのリクエストえは共通してクライアントからサーバに送る。

これらを以下のような流れで実行する。

  1. ユーザ名、realm、パスワードを「:」で連結し、MDS(Message Digest Algorithm)ハッシュ値を求める
  2. メソッドURIのパスを「:」で連結し、MDSハッシュ値を求める
  3. 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の生成方法は静的ファイルと動的ページでは異なる。

  1. 静的ファイルの場合

    Apacheのデフォルトでは、静的ファイルのETagの値はinode番号、ファイルサイズ、更新日時から自動で計算してくれる。 ただし、inode番号は、同一内容のファイルでもファイルシステムが異なれば別の値となる。 例えば、サーバを分散されている時に注意すべきである。 そのため、ファイルサイズと更新日時のみでETagの値を計算させるようにする。

  2. 動的ページの場合 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

サーバがメンテナンスや高負荷に耐え切れずサービスを提供していない時に発生する。 ツイッターのクジラが出たなどが有名どころ。 f:id:pokotyamu:20160510190718j:plain

エラー処理

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 サーバがメンテナンス中や高負荷に耐え切れず
サービスを提供していない時に発生する