「Webを支える技術」を目次だけ読んで中身を想像した

f:id:hiroga_cc:20170925214139j:plain

実は冗談でやってるわけではない。 こないだ読んだ「本を読む本」という本に、目次を読んで中身を想像するのは大事だって書かれていたような気がするので実践してみてる。

第1部 Web概論

Webの歴史を論じている。コンピュータが軍や大学にしかなかった時代から、アプリがWeb上で動くようになった現代までの流れを追う。 「Web APIをめぐる議論」にSOAPとWS-とRESTのことが書いてある。WS-って何か分からないが、RESTと対比されているのでクライアント側のフォーマットが決まっているプロトコルなのではないか。 RESTについて1章割いている。RESTfulなAPIをどう設計するかについて論じていると予想。URIの体系とか、サーバーサイドの実装のコツ(キャッシュをリバースプロキシにもたせるとか?)が書かれているのではないか。

第2部 URI

URIの仕様と設計について。仕様の章は、URIを要素に分解して説明していると予想。プロトコルドメイン、etc… 改めて説明しようとするとできないな。 設計の章は、ドメインが変わったときやAPIを追加したいときなんかの変化に強いURI体系について論じているのではないか。サービス/領域/リソース名 みたいに分解すると予想。

第3部 HTTP

基本→メソッド→ステータスコード→ヘッダ。HTTPの中身を要素ごとに解説すると予想。 ぶっちゃけレスポンスそのものって私は見たことほぼなくて、アプリケーションでformに梱包されているのしか受け取った覚えがない。 メソッド(DELETEとかPUTとか)にもページを割いている。GETとPOST以外使ったことないけど、態度として正しいんだろうか。

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

HTMLとJSONはわかるんだけど、microformatsAtomって何だろう。microformatsRDFと対置されるものらしい。Web以前のドキュメントの装飾とかに使われた古いフォーマットだろうか。 AtomRSSとかと一緒に見かけたことがある。ブログの更新とかに使われるんだろうか。これって現役の技術? JSONは知ってるけど、ハイパーメディアフォーマットって映像とか動画とか埋め込むフォーマットだと思ってた。誤解かもしれない。

第5部 Webサービスの設計

読み書きとリソースの設計。読みは置いといて、書き込みは排他制御とか。トランザクションリソースって聞き慣れない言葉だけど、DBだとトランザクションレベルって言葉があるから、そのWeb版かな? トランザクションレベルとは、逐次コミットとかまとめてコミットとかそういうやつだったと思う。 リソースの設計って何だ。と思ったが、DBではこんな形、Webサービスにしたらこんな形、の黄金パターンみたいなものかしら。

EclipseなしでStrutsを動かそうとして挫折中

f:id:hiroga_cc:20170923160637p:plain

jspファイルを読み込んでいる時に、ActionやActionFormと関係するところがうまく動かないらしい。。。

そもそもの背景

前にStrutsを使ってた時、そういえばEclipse任せ&プロジェクトの既存の設定任せで全然勉強してなかったことに気がついた。 なのでEclipseなしでStrutsのアプリを立てている。モダンなWAFとの比較もしたい。

やったこと

  • StrutsのWebアプリのひな形作成
  • jspファイル、Actionファイル、ActionFormファイルの編集
  • Tomcatの導入
  • Gradleでビルド

気がついたこと/ 困っていること

StrutsのWebアプリの作成

このチュートリアルに従ってやってるんだけど、このフォルダ構成は一般的なんだろうか。 前に使ってたところはどうだったっけ? www.atmarkit.co.jp

struts-config.xmlの設定が煩雑。railsがフォルダ構成を決めていることのメリットがちょっとわかった。 これが設定より規約か… ルーティングは、tornadoやflaskだとアプリ側で記載するから、

jspファイル、Actionファイル、ActionFormファイルの編集

jspがActionとかActoinFormを呼び出すときのエラーって、Pythonでjinja2とか使っても起きるんだろうか?

formはpythonだとdformってのがあるらしい。後で試したい。

Tomcatの導入

こちらを参考にさせていただいた。

koulog.hatenablog.com

まず、コマンドを自分で設定するっていうのが斬新だった! brew install hoge したら hoge が使えるようになるのに慣れてたせいで、

ln -s /usr/local/tomcat8.5.11/bin/startup.sh /usr/local/bin/tomcat-start

はほんと勉強になった。こうなってたのねえ。

Gradleでビルド

めっちゃ新鮮!もっと使いこなしたい。 こちらを参考にさせていただきました。 qiita.com

こんな感じになった。

apply plugin: 'java'

sourceSets.main.java.srcDirs = ['WEB-INF/src']

repositories {
    mavenCentral()
}

dependencies {
        compile 'javax.servlet:servlet-api:2.5',
                'org.apache.struts:struts-core:1.3.10'
}

依存性の注入を今は手作業でやってる。なんとかしたい。 あと、結果のクラスファイルは手作業でソースファイルと同じところにコピーし直してる。(これ動かない原因かな…?) 紐ついてるライブラリも、importするクラスファイルから逆に調べられるようになりたいなー。 どうしたらいいのかしら。

localhostでwebアプリを動かした時にサーバーの設定をした覚えがない

現場ではlocalhostにデプロイする時にWAS(WebSphere Application Server)の設定とかするのに、 家でrailsとかtornadoとかデプロイする時にサーバーとアプリのつなぎ込み?した覚えがない!なんで!

仮説

調べてみたら、tornadoはwebサーバーとしての機能も持っていた。 railsもサーバーとしての機能を持っているのではないか。 ただし、サーバーを別途立てて運用することもできるのではないか(railsunicornの単語をセットで見かけたことがあるから)

やってみた

railsアプリケーションを動かしてみるのが一番。 今回は他にもFlask(PythonのWAF)とPlay(Java/ScalaのWAF)も動かしてみた。

Rails

$ hello_app hiroaki$ rbenv exec rails s
=> Booting Puma
=> Rails 5.0.5 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.3.4-p301), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

調べたところ、デフォルトでPumaというwebサーバーが指定されているらしい。

Flask

$ python project.py
 * Running on http://0.0.0.0:5000/
 * Restarting with reloader

シンプルだなあ… Flaskは開発用のWEBサーバーを内蔵している、という記述を見つけたから、 Flask内部のWerkzeug(ウェルクツォイク、WAFのためのユーティリティ)が、同梱されているwebサーバと通信しているというイメージであってるかな?

Play

$ sbt run
[warn] Executing in batch mode.
[warn]   For better performance, hit [ENTER] to switch to interactive mode, or
[warn]   consider launching sbt without any commands, or explicitly passing 'shell'
[info] Loading project definition from /Users/hiroaki/Dev/lrn/play/play-java-starter-example/project
[info] Set current project to play-java-starter-example (in build file:/Users/***/play-java-starter-example/)

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Enter to stop and go back to the console...)

Akka HTTPというプロジェクトで作られたWEBサーバーが動いているらしいということはわかった。

結論

有名なWAFには、開発用のサーバーが一緒に入ってる、と考えて良いのではなかろうか。 いざ運用、という段になったら、専用のサーバーを立ててアプリを叩くように設定するのだと思われる。

久しぶりにfacebook messengerのチャットボット作って忘れてたこと

CIの勉強と便利ツール作成を兼ねて、久しぶりにチャットボットを作ってる。 構成はtoanado(pythonのwebアプリ用フレームワーク)+heroku

とりあえずおうむ返しまでできた。多分次回も忘れてることを書いておく。 f:id:hiroga_cc:20170917202951j:plain

便利コマンド

シェル

vi ~/.bash_profile (fb-バックエンド間の通信で使うtokenを設定する) source ~/.bash_profile

heroku

heroku login –app APPNAME heroku log -t –app APPNAME heroku config:set TOKEN_NAME=“token-no-nakami”

忘れていたこと

環境変数の設定周りがあやふやだった。

.bash_profileという、bashが起動時に勝手に読み込んでくれる、ユーザー単位の設定(中身はexportコマンドなど)が書かれたファイルを使う。 起動時に読み込むようにここに書いておく。書き込んだ直後は、source ~/.bash_profileとかで反映する。 sourceコマンドはファイルの中身を忠実に実行するコマンド。

heroku周りもあやふやだった。

pythonを動かすには、Procfileはじめ色々と設定ファイルが必要だった。 前回作ったのがなければまずかった。

facebook-heroku間のつなぎ込みもあやふやだった。

手順はこんな感じ。 facebook->バックエンドの通信のtokenの正解をバックエンド側に設定する。 facebookの開発者向けダッシュボードからWebhooks >> 設定。

それが終わったら、今度はバックエンドからfacebookに返事。 facebookの開発者向けダッシュボードでページのサブスクリプショントークンを取得し、 それをバックエンドに設定。それができたらメッセージを送信。 このフォーマットは面倒なので前に作ったやつを毎回パクってる。

CIについて

今やってるとこなんだけど…herokuとgitはすごく楽チンなんだけど、redmineのつなぎ込みがなんかうまくいかない。 難し〜。

継続的インテグレーション自前でやってみる計画

「チーム開発実践入門」を読んでみて、仕事以外でやってみたいなと思いつつある。 こういうのは妄想をたっぷり膨らませておくのがモチベに繋がる。なので計画立ててみた。

f:id:hiroga_cc:20170916124440j:plain

最終目標:

マスターブランチにマージしたら自動でテストしてデプロイしてくれること。チケットもいい感じに更新してくれること。

ステップ1

チケット駆動でやりたいので、まずはRedMineサーバーを立てる。 若干古い感じがするけど、SIerの現場でためらいなく使えること(要はOSSであること、実績があること)が今回は大事。 AWSでDockerで建てられるっぽい。

ステップ2

それが終わったら、バージョン管理ツール、CIツール、本番環境を用意する。 バージョン管理はGit、中央のリポジトリGithubを使えばよし。実業務を念頭におくと、アプリ用とDB用でリポジトリを分けるべし。 (アプリとDBはN:1の関係になると思われるので)

CIはJenkinsを使ってみる。Githubとの連携を考えるとTravisCIがいいらしいんだけど、SIerの現場でも使えることを考えるとOSSが良い。 これもAWSでDocker使って立てる。

本番環境はHerokuにする。 多分Docker経由でAWSにあげるのが良いんだろうけど、それは後でいい。

ステップ2の鍵は、Github - Jenkins - Herokuのつなぎ込みだと思う。特にJenkins、触ったことないから画面が想像つかない!

ステップ3

アプリとDBを作ってローカル、ついでHerokuで動かす。 チケット管理をGithub, Jenkins, Herokuに連携させる。

ステップ4

UTを書いてJenkinsに登録する。 カバレッジを楽チンに見られるようにする。

読んでみて

大体はSIerの現場でも経験したことがある(たとえExcel管理であっても)んだけど、DBのスキーマリポジトリで管理するのは気がつかなった。 あとはローカル環境にDBを構築することも。ローカルから開発環境のDBを参照するのって普通じゃなかったんだね!

読むだけじゃなくて実際に手を動かしながら参照する本なのかもしれない。

RPG(プログラミング言語)はどうして自分には読みづらいのか

最近考えたことの棚卸し。

PRGで書かれたプログラムのソースのやりたいことがさっぱり分からない。 コンピューターの性能がまだ低い時代の言語だから、人間にもわかりやすい表現で書くことが難しかった、と思ってるけど正しいんだろうか。

仮説なんだけど、コンピュータのリソースが貴重だったから専用の紙にプログラムを書いて、それからコンピュータに入力していたのでは。 そのせいで、文法がものすごく硬い。

調べたら、「自由形式」というソースの記述方法を使っていないらしい。 どうなるかというと、命令文がソースコードの特定の桁位置から始まる必要がある。

f:id:hiroga_cc:20170908070928p:plain

(wikipediaより)

最近のプログラミング言語がいかに恵まれているかもわかりつつある。 こんな仕様がない(または、あるけれど私の見るソースでは使われていないか、気づいていない)

  • 器用なIF文がない。 switch文とか三項演算子とかない。よってIF文がものすごく続く。

  • 便利なループ処理がない。 doループしか見た覚えがない。for,whileがない。mapとか当然ない。

  • エラーの例外処理。 try - catch- finallyとかない。

  • インデントが自由に使えない。 IF文とかFOR文の中身にインデントがかかってないのを想像してみて。

  • 戻り値を変数に格納しないで使ってるとこ見たことない。 if (getHoge()){ ~処理~ }; みたいな書き方はせず、毎回変数に格納する。あっちこっちの変数を経由するので何を指してるのか分からなくなる。

  • オブジェクト(最新の言語仕様にはあるらしい) 全部プリミティブ型。timestampを呼び出して年月を取得するみたいなことはできない。共通クラスとかない。

  • 標準ライブラリがない。 カレンダー型とかtimestamp型とかそういう便利なものを見た覚えがない(そもそもimportがないと思う)

  • ORMはおろか、SQLがない。 何を言ってるのか分からないと思うけど、DBMSがやっていることと同じ処理をやっている。 テーブルではなく、ファイルを1行づつ読んでる。

こうした理由から、処理が何を言っているのかさっぱり分からない。 いまのところのベストは設計書に補足を書きながら読み進めること。なんか面白い経験してるよね…

ショッカソン2017ひとり反省会(アップデート版)

8月26日(土), 27日(日)の2日間、ショッカソン(触覚デバイスを使ったハッカソン)に参加した。 ハッカソンを通しての自身の反省と、運営について感じたことをいくつか。

ちなみにハッカソン自体はチームメンバーにも恵まれ、先生方から勉強になるフィードバックをいただき、初のショッカソンの雰囲気も体験できてすごいよかった。

ひとり反省会

チーム「のんあーる」として参加したけど、なんだか小さくまとまってしまったと思った。

※来場者の皆さんに楽しんでもらえたと思うし、チームメンバーは素晴らしく専門性を発揮していたけど!

自身の担当パート(VRメガネ)は改良の余地があったし、チーム全体に働きかけてもっと面白いアイデアを出したかった。 それができてなくてちょっとショック。

ハッカソンに悪い意味でこなれてきているせいで、「コミュニケーションをサボってる」ことが原因だと思う。

自分のパートで

VRメガネでも、「自分が傾くと画面がもっと傾く」とか「ピントが勝手にずれる」とかやりたいことが他にもあった。 ところが、Unity上で画面を赤くするだけで2日目の朝までかかってしまった!(徹夜ではない)

実装力がないのは仕方ないけど、優先度のつけ方と相談が減っていることが問題だと思う。 どうしてそう思ったかというと、1日目にめちゃくちゃ悩んだ「なぜかGoogle CardBoardでも視野が複眼にならない」問題について 自分がドツボにはまっている時に、チームメンバーの@TJ16thさんがググってパッと解決してしまったから。 TJ16thさんは(多分)Unityの専門家じゃないんだけど、困っていることはちゃんと共有しなきゃと思った。

もっと言えば、実装の順番も違ったと思う。 佐藤先生から「画面が傾いたらどう?」ってアドバイスをもらった時、「あ〜赤くするのにこだわってないでそっちやれば…」と思った。 こういう優先度付けをちゃんとチームの人と話し合っていれば…悔しい…

チーム全体で

チーム内で「これって本当に酔ってる感覚?」とか「気持ちよい酔いってなんだろう?」とかもっと話すよう働きかけたかった。 お客さんからたくさん指摘をもらって、そういう議論が足りなかったことがわかった。

例えば、気持ち良い酔いを目指していたはずなのに、「気持ち悪い〜」という反応がたくさん出てしまったこと。 逆に気持ち悪い酔いを目指しました!でも全然ありなんだから、そういう方向で考え直すべきだった。 そうすれば、もっと触覚をオーバーにするようなアイデアが出たかもしれない。

他には、画面がなんで赤いのか全然伝わってなかった&自分自身も説明に困った。 実は初めは黒く染まるように設計していて、「めまいを再現しました!」っていうつもりだった。ただ、黒くしているはずが灰色になってうまく伝わらなさそうだったので、じゃあ赤だ、みたいな感じで実装してしまった… なんでチームメンバーに相談しなかったんだろう。

運営について感じたこと

自分も近いうちにハッカソンに運営側で参加してみたいなって思うので、その観点から気が付いたことを。

1日目~2日目通して審査員さんを呼んだり、各チームに行き渡るだけの協賛を取ってきたり、etc…ショッカソン運営の方々には本当に感謝してます! 一方で、初めて参加する人にもっと親切にできたかも?って思いました。 特にアイデアソンとデモ以降の流れについて。

イデアソンでは、特に発表〜チーム決めの時間を倍くらい取った方が、やりたいことが決まっていない人に親切だと思います。 今回は投票上位のアイデアをプレゼン→参加者はやりたいアイデアのところに並ぶ、という流れでしたが、 1. 情熱枠(投票では上位に入っていないけど、やりたいことがある人枠)をやりたい人がいないか聞いてみた方がよかったかも 2. 各アイデアの発表者に参加者がインタビューしに行く時間があってもよかったかも と思います。

  1. については、上位アイデアの中に一人で複数アイデアを出している人がいたり、発案者が「他のやりたいです」って言っているものがあったので、 その分だけは情熱枠を募ってもよかったんじゃないか?と思いました。
  2. については、単に焦らずにチームを決めたかったというのがあります。笑 混雑していてあんまり話を聞く時間も取れなかったので…

限られた時間である程度の人数のいるチームを作成する(完成度を保証する必要があると思うので)ってとても大変だと思うので、もし自分が運営で↑をやれって言われたら準備できるかちょっと不安ですが…。

デモ以降の流れについては、「他チームのデモを体験する時間がどこか分からなかった(来場者向けデモとは別にあると思った)」という意見をチームメンバーから聞きました。 プレゼン以降は作品に触る時間ありません、っていうのがわかっていたら…と思います。 そうすればチーム内でシフトを組んで他のチームのデモの体験とかもできたと思うので、残念でした。