makopi23のブログ

makopi23が日々の生活で感じたことを気ままに綴るブログです。

「RESTful#とは勉強会13」に参加しました

2016/2/23(火) 「RESTful#とは勉強会13」に参加してきました。

DoorKeeper
https://rubychildren.doorkeeper.jp/events/39034

Togetter
http://togetter.com/li/942251

場所は高円寺のヴァル研究所さんです。
参加者は30人くらいでしょうか。

毎回、以下の書籍をターゲットに読書会やら、特別ゲストによる講演やら、ワークショップなどが催されます。

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)
山本 陽平
技術評論社
売り上げランキング: 7,978


今回は読書会形式ではなく、AWSJの西谷 圭介さんを特別ゲストとして迎え、プラットフォームにAWSを使用しているサービス「駅すぱあとWebサービス」のAPIやドキュメントを題材に、公開レビューという観点で学ぶ、という位置づけの勉強会でした。

RESTプロフェッショナル川村さんが書いてくださった、この日のポイントです。




グループワーク



最初に4~5人ずつのグループに分かれ、「駅すぱあとWebサービス」を題材に、どこがRESTfulか、どうしたらRESTの規約に近づけるかなどグループで話し合う時間が1時間ほど設けられました。
ウチのグループは「駅すぱあとWebサービス」のAPIソリューション 無償提供版 ドキュメントを題材に話し合いました。
その中で出た意見は以下のとおり。

  • レスポンスデータの名称の先頭が大文字だったり小文字だったりと、統一感が無い。
  • レスポンスデータの要素が複数を想定しているのに、名称が複数形でなく単数形になっている。
  • APIのURLが予約語と被ってる。例えば/railとかは、Rails使いだとハマるかも。
  • レスポンスデータに必ずengineVersionがあるが、APIを叩く側のユーザにはこの情報はいらないんじゃないか。
  • エラー時に、404のようなHTTPステータスコード以外にも、エラーレスポンス内に「内部エラーコード」を持っているのが興味深い。
  • 存在しないクエリパラメータを指定すると、「もしかして XXX」のようにサジェストしてくれるのが面白い。
    • URI: http://api.ekispert.jp/v1/json/station/info?code=22828&type=rail:nearrail:exit:welfare&key=XXX&test=abc
    • レスポンス: {"ResultSet":{"apiVersion":"1.26.0.0","engineVersion":"201602_03a","Error":{"code":"W400","Message":"指定されたパラメータ(test)の名前が間違っています。 もしかして: type"}}}



「駅すぱあと」のWeb APIがC言語で作られている理由



グループワークの後、ヴァル研究所の見川さんより、「駅すぱあとWebサービス(API技術)がC言語で作られている理由」について紹介がありました。
それによると、

  • 「駅すぱあと」のエンジンがC言語で開発されているので、エンジンを直接コールするのにWebサービス(API技術)もC言語にしているため
  • Webサービスをバイナリ提供するため

という理由があるそうです。
エンジンがC言語なのは、顧客が増えた時にでも使えるよう性能面を考慮してのことだそうで、それが今のWebサービスに至ったとのこと。
Rubyの実装部分は薄くし、基本機能はC言語で再実装し、Webサービスの本質的な機能はXML-RPCに寄せているそうです。
ちなみに「駅すぱあと」のAPIはRestfulではなく、Restfu(≒Rest風)なんだそうなw


西谷さんによる公開レビュー



お次はグループワークのお題に沿って、AWSJの西谷 圭介さんによる「駅すぱあとWebサービス」の公開 処刑 レビューです。
西谷さんは自称「REST原理主義者」なんだそうな。API設計に深いこだわりがありそうです。
まず最初、そもそも「Restfulとは?」という問題提起から入りました。西谷さんは、Restfulとは
  • リソース指向なURI設計をする。つまり、リソースという観点でパスを切ってURIを設計する。
という捉え方をしているとのこと。

その上で、ディスカッションを交えながらレビューを進めて、以下の様な意見が出てきました。

■ APIドキュメントの見やすさ
  • 「Webサービスドキュメント - API」が見にくい。それは、ドキュメントの並びがリソース単位じゃないから。
  • /courceとか/stationという文字列が、あちこちのカテゴリに入っている。
  • Restfulの原則として、「リソースに対してCRUDしていく」というのがあるが、その観点では見づらい。
  • 一方で、カテゴリ毎に纏まっているので、それはそれで見やすい。目的ごとに探しやすい。
  • リソース毎に分けたAPIドキュメントと、カテゴリ(目的)毎に分けたAPIドキュメントの、両方が提供されていれば良かったのでは。


■ 単語の区切り
  • /passStationで、単語区切りのSが大文字になっており、キャメル形式になっている。
  • URIで、大文字はあまり使われない。単語の区切りはハイフンを使うパターンが多い。passStationでなく、pass-station。


■ * (アスタリスク)
  • API仕様のURIすべてに*が含まれているが、初見には謎すぎる。誰もがそう思うはず。
  • *にはフォーマットを指定するらしいが、普通は入れないよね。
    • ⇒ 最近の設計だとHTTPヘッダに書いたりするが、いろいろあってこういう設計になっている。こだわりは無い。 by 見川さん


■ バージョン指定
  • API仕様のURIすべてに /v1 というバージョン番号が含まれている。
  • v1が公開されてから6~7年経っている。v2が出る予定は今のところ無い。 by 見川さん
  • バージョン番号をURIに含めるかは諸説ある。
  • バージョン番号はリソースじゃないからURIに入れないという考え方もあり、その場合はクエリパラメータとして付けるか、リクエストヘッダに入れるかすることが多い。
  • バージョンによってAPIを切り替えられるようにするならURIに載せてしまったほうが良いのでは。
  • バージョン番号がURIにある方が、ヘッダやクエリパラメータにあるより人間にとってはわかりやすい。


■ 単数形
  • リソースがすべて単数形で表現されている。基本的には複数形を使っていくのが良い。
  • GETメソッドで複数取得できるなら複数形にし、単数も取れるならURIの後ろに /?id=3 みたいに指定して取得するのが良い。
  • 運行情報路線のリストを取得するのに /service/list とするのはあまり良くない。
  • /service とし、GETメソッドでアクセスするとリスト構造が取得できるようなURI設計が良い。


■ CRUD
  • 提供しているAPIはすべてGETメソッドを想定しているのに、URIに /create/editという単語は不自然。
  • CRUDはHTTPメソッドに対応させるのが大原則。
  • createならPOSTメソッドだし、editならPUTメソッドを使う。createやeditという単語はURIに含めない。
  • 経路(cource)を更新(edit)したい場合は、URIで /course/id=xx と更新対象を指定し、更新内容はリクエストボディに持たせて投げるのが普通。


■ 敢えて /create とした理由 by 見川さん
  • /course/create としたのは、「パラメータに与えた経路を作り出す」という意味を込めて設計した。
  • 「駅すぱあと」は経路探索がウリなので、一部のお客様のニッチなニーズに対応するために用意した再検索用のAPIである。
  • 経路の生成コストが大きいので、組み合わせの情報だけ保存しておけば経路を再現できるような仕組み。


■ 敢えて /edit とした理由 by 見川さん
  • 探索した結果の経路に対して特定の操作をするAPIである。
  • 特急料金、グリーン席料金、自由席料金、それぞれ計算する必要があるので、それを指すのがedit。(???)


■ APIのアクセスキー
  • 「駅すぱあと」のAPIアクセスキーはWebで申請できるが、お客さんには紙で送付するビックリな運用になっている。
  • 課金を含めてすべてをWebで回すまでには至っておらず、会社の諸事情もある。
  • URIのクエリパラメータにkeyを含めてアクセスすることはセキュリティ上ありえない。
  • 一般的には、リクエストの認証ヘッダ(Authorizationヘッダ)にkeyは格納する。


■ リソースの相関関係
  • リソースの相関関係が人間にとって理解できないと意味が無い。
  • 特定のリソースがあるリソースにぶらさがっているという構成が理解できないといけない。
  • 「駅すぱあと」は「鉄道」というドメインに偏っているので、URIの表現の仕方が難しい。日本語の説明を見ても、違いとかよくわからない。


■ 時刻表(timetable)
  • /plane/timetable と、飛行機の下に時刻表がぶら下がっているが、この上下関係以外にも別の表現がありえるのでは。
    • APIはGETメソッドしか許容していないので、時刻表(timetable)の更新用のAPIは無い。 by 見川さん
    • 時刻表ファイルの切り替えで更新を実現している。 by 見川さん
    • 時刻表の更新は1~2週間毎くらいで更新が頻繁に入っている。 by 見川さん


/dataversion
  • dataversionって何?
    • このサービスが持ってる鉄道とかバスの更新情報を示している。 by 見川さん
    • このWebサービス自体のバージョンとかも返している。(apiVersion) by 見川さん
    • APIを使う側にとっては、いつのAPIの情報を使っているのかを知るためのもの。 by 見川さん
  • dataversionって冗長じゃない?という声も。


■ /station/info
  • あえて /info を用意しているのは?
  • /station に比べ、 /station/info は付属的な情報(あまり必要とされない、微妙な情報)を提供する。 by 見川さん
  • その用途の違いがあるので/stationと/station/infoを分けている。


■ /search
  • searchって名詞じゃなく動詞のようだけど、リソース名としてどうなの?
  • 「探索結果」という名詞の位置づけ。 by 見川さん


■ APIドキュメントのメンテナンス
  • ドキュメントはぬくもりを感じたが、メンテナンスどうしているか?
  • APIドキュメントはもともと自動生成していたが、最近はGitHubで管理して複数人でレビューする手動管理にしている。デプロイは自動。


■ リソース名が日本語
  • /teiki って、「定期」という日本語が混じっているのが気になる。
  • ⇒ 日本の定期券は独特の事情があるので、あえて日本語のリソース名を付けている。


■ コンテキスト依存
  • クエリパラメータの名前は同じだけど、コンテキストによって意味が変わるものがあった。


■ APIへのリンク
  • APIのレスポンスにリンクが無い。次に取り得る状態をリンクとしてレスポンスに含めるのが良い、という指針に沿ってない。
  • /stationを呼び出した時に、レスポンスで/station/infoを含めて返したほうが良いのでは。
  • APIドキュメントのリンクも合わせてレスポンスに入れてしまえばいいのでは。


http://schema.org/
  • リソースや要素の名称を考えるときに役立つサイトとして schema.org というのがある。
  • 共通の語彙を纏めており、標準的に使われる可能性が高い語彙が登録されている。
  • 標準的なボキャブラリはこのサイトから選択すれば良いのでは。
  • 鉄道情報のボキャブラリも、 https://schema.org/TrainStationhttps://schema.org/TrainTrip が参考になるかも。
  • teiki(定期)もschema.orgに登録してもらえば良いかも。


ResultSet
  • レスポンスデータのルート要素が必ずResultSetになっているのが気になった。
  • 必ず同一のリソースで括る、という思想で、抽象的な階層を1段設けたかったのでそうした。 by 見川さん
  • とにかくResultSetを取得すれば、そこに何かが入っている、という状態を作っておきたかった。 by 見川さん


■ light / full / extreme
  • fullがデフォルトで、デフォルトから足したらextreme、デフォルトから引いたらlight、という思想だったが、今は微妙になってる。
  • extemeはベータ段階で適当に付けた名称で、後で直す予定だったが、リリース直前に疲弊して直せなかったままになっている・・・ by 見川さん
  • light/full/extreme は、構造が同じならクエリパラメータで指定するの良いのでは。構造が別ならURIを分けて別リソースとした方がいい。


■ AWSのAPI
  • 本当に糞・・・。Rest APIと謳っているのに、全然そんなことはない。


■ 駅すぱあとのAPI
  • 全体的に綺麗なAPI設計になっている。
  • 昔からあるAPIなのに、最近のAPI設計のあるべき論からも外れていないし、ちゃんと昔から設計やってたんだな、と感じる。


■ 時刻表の秒
  • 鉄道の時刻表って秒単位で列車情報を持っていると思うが、秒単位をデータとして保存するのはどう考えているか?
  • 秒単位でデータを持っているが、現状は公開していない。分単位のデータを公開している。 by 見川さん


■ 緯度経度の情報
  • 緯度経度、DEG形式とPOT形式の両方返すのは、使う側の利便性を考慮し、計算の手間を省くために2つ持っている。



■ SDK
  • AWSなどはSDKが提供されているが、駅すぱあとはSDKは用意されていないのか?
  • 特定言語に向けたSDKを用意するのは必要だと思ってるが、そこまでおいつけてない。 by 見川さん


■ リソースモデリングパターン

勉強会終了後の西谷さんのブログ




とても勉強になるレビューでした。ありがとうございました。


勉強会終了後の川村さんのブログ




いつも事前準備と丁寧なフォローありがとうございます。


感想


とても学びの多い勉強会でした。
実際のAPIを題材に、実際に頭を使ってみんなで考えた後、有識者の見解も聞く。この理想的なサイクル。
とても実用的で、多くの気づきを得ることができました。こーゆうのは良いですね。

毎回の勉強会で欠席率が非常に低いという点は、こーゆう充実した内容と運営、そして穏やかな雰囲気があるからこそだと思います。
次回の勉強会も楽しみにしています。

関係者の皆様、ありがとうございました。

PS:
帰り際にスマホ紛失疑惑でお騒がせし、スミマセンでした・・・&お気遣いありがとうございました。

スポンサーサイト

"【東京】JJUGナイトセミナー 「Java EE 7徹底入門」の著者が解説! - Java EE 7特集"に参加しました

2016/2/15(月) "【東京】JJUGナイトセミナー 「Java EE 7徹底入門」の著者が解説! - Java EE 7特集"に参加してきました。

DoorKeeper
https://jjug.doorkeeper.jp/events/38857

Togetter
http://togetter.com/li/938867

場所は日本オラクルさんです。
参加者は200人くらいでしょうか。

以下の書籍をターゲットとした勉強会なのです。

Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築
寺田 佳央 猪瀬 淳 加藤田 益嗣 羽生田 恒永 梶浦 美咲
翔泳社
売り上げランキング: 72,949


毎月参加してるJava読書会で1月からちょうどこの本を読み始めたのですが、良い機会ということで参加しました。


Java EE 7徹底入門 概要説明 (猪瀬さん)
20160215 01 java ee7徹底入門 概要説明 from Jun Inose


表紙が白猫の理由や、てらだよしお退職事件などの裏話があり、本への親近感が湧きますね。
誤記が多い、とありますが、確かにJava読書会でも誤記たくさん見つけてます・・・
後日、フィードバックされるかも。
あと、弊社でもStruts1ベースの自社フレームワークを刷新するプロジェクトが絶賛進行中ですが、こーゆう日本語書籍で最新フレームワークを解説いただけるのはすごく有り難い。


プレゼンテーション層の開発 JSF (加藤田さん)
JavaEE7徹底入門 プレゼンテーション層の開発 JSF from Masuji Katoda

  • Java EEは、2年前は洋書の本しか無かったが、今回、翻訳でなく日本語で書いたとのこと。
  • JSFはコンポーネントを主軸にコードを作成するので、コンポーネント指向と言われる。
  • カスタムコンポーネントは、タグライブラリを独自に作る機能。フレームワーク作る人とかにしか関係ないので本では省いた。
  • イベントハンドリングでValue Change Eventsというのがあるが、実際はAjaxでチェックすることが多い。
  • ビーンバリデーションのグループ化機能は、複数の画面でバリデーションを微妙に変えたい場合に使う機能。
  • Java EEの思想として、「なるべくJavascriptを使わずに開発できるようにする」というのがある。
    • JSF2.3でWebsocket対応する。
  • MVC1.0はアクション指向フレームワーク(Strutsみたいな)。それに対し、JSFはサーブレットを基本としたコンポーネント指向。
    • MVC1.0はJAX-RSがベース。
  • 今後のプレゼンテーションの選択肢は、3パターン。
    • JSF
    • JAX-RS + クライアントサイドフレームワーク (AngularJS、React、Backbone.jsなど)
    • MVC1.0 + Web Component?
  • どのアーキを選択しても今後はコンポーネント指向に収束する。人間のイメージしやすい開発なのかな、と思う。
  • タグライブラリは最小限の機能しか提供していない。なのでJSF関連のコンポーネント系ライブラリを併用して使う。

ビジネスロジック層の開発 CDI,EJB (羽生田さん)
3.Java EE7 徹底入門 CDI&EJB from Tsunenaga Hanyuda

  • CDIとEJFは排他的ではない。組合せで解決するのが良いのかな、と思う。
  • EJBは昔、ディスられることが多かったが、この先も使ってもいい技術。本に、上手く使う設計ポイントを書いてる。
  • CDI
    • スコープ定義を使って、そのスコープで生きているものをどう使うかがポイント。
    • スコープ定義はコンテナで作られて消えていくまでのライフサイクルであり、5種類ある。
    • それぞれのライフサイクル、これだけ覚えておけばCDIは使える。
    • @ConversationScopedは、作る側が生き死にを決められる。
    • EJBと比較するとリソースメリットがありそう、という表現の、「ありそう」に行間がある。
    • CDIは層を繋ぐ。業務ロジック層だけでなく、プレゼンテーション層や永続化層など、かなり広く渡る。
    • CDIはよくも悪くもWeld(CDIのリファレンス実装)。
    • GlassFishと商用サーバでWeldのバージョンが異なるので、バージョンを抑えておかないと死ねる。
    • CDI.select()は良く使う。BeanManagerの取得元としてはあまり使わない。なぜなら、@injectで取れるので。
    • CDIの小ネタで、CDI.current().toString()とやると、"Weld"という文字列だけ返してくる・・バージョンくらい返してほしい。
    • CDIProviderは覚えなくても大丈夫。
  • まとめにある「密結合させる」というのは、「injectじゃなくてnewする」という意味。
  • @Conversationスコープ使おうとするなら、本当に必要なのか問うべき。


バッチアプリケーションの開発 jBatch (猪瀬さん)
20160215 04 java ee7徹底入門 jbatch from Jun Inose

  • jBatchはSpring Batchから多くのアーキテクチャを継承している。Spring Batchの方が高機能。
  • Javaでバッチを実行する4つの方法
    • 1と2の独自Javaバッチだと、Java EEの機能を使うときにライブラリが必要となるので、APサーバで動く他の部品との共有が難しい。
    • 3はバッチがHTTP経由になるので、HTTPリクエストタイムアウトの可能性がある。
  • ジョブ定義はXMLで書く。本ではあまり丁寧に書いてないが、XSDを指定するとエディタがXMLを補完してくれる。
  • 補助機能のコンテキストは2種類あり、プロパティを引数に渡せる。プロパティに設定を与えることができる。


★感想:
Java読書会でこの本を読み始めてまだ2回で、JSFしか触れてなかったので、このイベントでJava EE 7の全体間が分かって有意義でした。
著者さん直々に説明してくださるのは良いですね。

Struts1やSpring Bootは触ったことありますが、Java EEはほぼ初めてなので新鮮です。
Java標準ということもあり、Java EEの知識は他のフレームワークとの併用でも活かせるのではと期待してます。
(ビーンバリデーションとか)

関係者の皆様、ありがとーございました。

体重108kgで「第36回 館山若潮マラソン」を無事完走してきました!

2016/1/31(日) 「第36回 館山若潮マラソン」を無事完走してきました。

館山若潮マラソン 公式ページ
http://www.tateyama-wakasio.jp/



館山若潮マラソンへの参加は今回が五回目です。
初マラソンがこの大会だったので、とても思い入れがあり、大のお気に入りなのです。

先月、湘南国際マラソンをいい手応えで走ることができました。
ちょうど先週も、NBLバスケ観戦の為に片道10kmの代々木第二体育館まで走ったりと、けっこう距離は走ってきました。

そんな俺が、この日のために作り上げたカラダを見よ! (マラソン当日朝の体重計測)


108kg!クソワロたw
過去最高の体重・・・先月の湘南国際マラソンから2kg増えてるし・・・

朝4時に起き、両国発の臨時特急に乗り、朝8時半くらいに現地に到着。
20160131_tateyamawakasio1.jpg

この日はうっすら曇りで風はほとんどなく、気温も8℃前後と、これ以上ない絶好のマラソン日和でした。

着替えとトイレを済ませ、今朝、体重計に乗った後に作ったお手製の仮装ゼッケンを背中に装着!


この仮装ゼッケンを見て奮い立った、俺の後を走るランナーよ!俺の背中に着いて来い!(笑

スタート地点にて。
20160131_tateyamawakasio3.jpg

予想タイム5時間30分のレーンに並びます。過去最高タイムは初マラソンで出した5時間35分。
あれ以来4年間更新できてないので、なんとか更新したい・・・!

走ってる最中は、背中に付けた108kgの仮装ゼッケンが目立つためか、いろんな方に声をかけていただきました(笑
「すみません、面白いんで後ろから写真取らせてもらっていいですかw」とかお願いされて、背後からパシャリとか。

スタート時は曇りだったんですが、正午あたりから日が差してきてちょと暑いくらいでした。
半袖半パンを選択したのは正解でしたね。

館山若潮マラソンは高低の出入りが激しい難コースですが、個人的にはとある作戦を徹底した。それは

20km地点以降は、上り坂は歩く。

これだけ。
42.195kmを歩かずに走りきるのはまだ無理なので、どこかで歩かねばなりません。
それなら、坂を走って登るのに体力を使うより、ここで温存して平地や下り坂に使うほうが良いと判断しました。

30kmの山頂付近で5間30分のペースメーカーに抜かれました。
これで自己ベスト(5時間35分くらい)の更新はほぼ無理だな、と思いましたが、このあたりで抜かれるのは想定内でした。
ただ、まだ足も体力も残ってて、ここまでの調子も決して悪くなかったので、5時間40分くらいはいけるかな、と・・・

33km地点の最終関門を無事クリアして、あとは平地の海沿いをゴール地点までひた走ります。
108kgの仮装ゼッケンを背に掲げながら・・・

そして、



ゴール地点で完走証を受け取ります。なんと、自己ベスト!
20160131_tateyamawakasio4.jpg

朝の体重計で108kgの数値を叩きだした時はどうなることやらと思いましたが、このタイムは驚きです。
惜しむらくはネットタイムで5時間30分を切れなかったこと。あと58秒・・・!
他のランナーから見れば遅すぎるタイムなんでしょうが、108kgの自分としては一生懸命頑張った結果なのです。

ちなみに、ゴール後に楽しみにしていた恒例の豚汁ですが、今年はもう品切れだったようで・・・
とても残念でした・・・。

帰宅してランナーズアップデートを確認。こんな感じ。
20160131_tateyamawakasio2.jpg


★感想:
この体重で自己ベスト更新が出来て、嬉しさよりも驚きの方が大きかった(笑
しかも館山若潮マラソンは他の大会に比べ難コースで有名なので・・・
今年の初マラソンでしたが、幸先良いです。今年もフルマラソンを完走できる頑丈な体に感謝。

あと、やっぱ沿道で温かい応援を送ってくださる町民のみなさんの気持ちが嬉しいですね。
温かい声援や私設エイドでのおもてなし。挫けそうな心と体、何度も元気づけられました。

来年もまた参加します。次は5時間30分切りを目指して~