しがないソフトウェアエンジニアの探求日誌

六本木一丁目で働くソフトウェアエンジニアのブログ

REST についての koriym さん開催のトークイベント 「Final Object #0」 トーク内容まとめ(参加レポート) #FinalObject

@koriym さんによって主催された、Final Objectというトークイベントに参加してきました。 株式会社TRASTA が会場で開催されました。

f:id:khigashigashi:20190219192526j:plain
会場の様子

ハッシュタグは、 #FinalObject でした、Togetter でまとめておきました。

togetter.com

このイベントは、招待制で、主に @koriym さんと@kseta19さんが招待した約20名の方が参加されていました。 普段、カンファレンスやOSSで活躍されている方々ばかりでとても密度の高い場で、@koriym さんのトークをガッツリ聞くという会になりました。 タイトルにも記載していますが、今回のトークのテーマは、 REST でした。

以下、話していただいたことを速記でまとめていったものを構成し直したので、ぜひご覧ください。

イベントの趣旨

個人的なトークイベントをやってみたい意図があった。特にやりたかったのが、「話すことに主眼をおいた会」だった。
今回のイベントに、「○△□」という仙厓義梵の絵を設定した。

仙厓義梵《○△□》「わかる」がわかるか──「中山喜一朗」:アート・アーカイブ探求|美術館・アート情報 artscape

仙厓義梵でよく引用されて有名なのが、「指月布袋画賛」という絵。

blogs.yahoo.co.jp

「愚者は指を見る」と説明されるこの絵は、とても楽しそうに描かれている。このことから、「真理を求める人達が、その過程を楽しむ意味」というふうに捉えられたそう。

戻って、「○△□」という絵は、もっとも複雑な絵として説明されるが、これは、「真理へ向かっていく過程」を表しているふうに考えた。具体的には以下。

  • 「□(四角)」が拡散する問題
  • 「△(三角)」が自分なりの結論を表している
  • 「○(丸)」が真理を表している、開発者にとっての真理

これら3つの「○△□」はつながっていることから、「拡散している状態(「□」)から真理(「○」)へ近づいていく」ということを表現していると解釈した。
今回の会では、 Think, "Talk" and Code という言葉を使っている、これも「○△□」に照らし合わせて次のように考えている。

  • Think 拡散している状態で考える
  • Talk 自分なりの考えを話す
  • Code 開発者にとっての真理:コーディング

今日のテーマは「REST」。RESTについては次の記事で、ほとんどの人が理解していないと指摘されているテーマ。

blog.steveklabnik.com

マーシャル・マクルーハン の、"誰が水を発見したかは知らないが、それが魚でないことだけは確かだ" という言葉に近い状態で、このテーマを理解することは難しい状態にある。

前段:全てを結ぶ力

まず、以前のPHPカンファレンスで発表されていた「全てを結ぶ力」という内容を、RESTについて話すために話されました。 koriym.github.io koriym.github.io

Hypertext

  • Hyper Text Markup Language
  • Hypertextとは、複数のテキストを相互に関連付け、結びつける仕組み
  • Vannervar Bush(原爆を作った人)の AS WE MAY THINK
      - 人は本のように序章・次章といった風に考えない
      - 思考はそれぞれリンクされている
    
  • Ted Nelson が、HyperTextという言葉を生み出した
  • Bill Atkinson
    • HyperCard
    • HypertextをGUIシステムとして実装した
    • プログラムはテキストで書かれていない、ボタンや壁紙などの中に書かれている
      • VISUAL BASICのイメージが身近に想像できるかも

WWW 1991

REST の本編

RESTful WEB APIについて

Roy T.Fieldingによる論文によって展開された理論。

www.ics.uci.edu

RESTについての本で、RESTful Web APIs: Services for a Changing World (English Edition) の特に「Appendix C. An API Designer’s Guide to the Fielding Dissertation」が良い内容。今日の話はここについて。

f:id:khigashigashi:20190220224705j:plain
https://www.amazon.co.jp/dp/B00F5BS966/ref=cm_sw_r_tw_dp_U_x_qluBCbZ9ZK2HY

Web APIアーキテクチャスタイルがある。

APIにはいくつかのアーキテクチャスタイルがある。

www.apiacademy.co

  • Tunneling: SOAP
  • Object: CRUD
  • HyperMedia: REST
  • Query Style: GraphQL
  • Event Driven Style
    • メッセージ思考
    • URI Styleなどと違いクライアント・サーバに会話がない一方通行

今回の話で、FocusするのはHypermedia Styleである。

roy.gbiv.com

Webの特性

Webの4つの特性

  • 低い参入障壁
  • 拡張性
  • 分散ハイパーメディア
  • インターネット規模

低い参入障壁 = Easy

  • Webブラウザにマニュアルは不要
    • ex FTPならコマンド覚えないと
    • サーバー側も設置が簡単

拡張性

  • 変化し続けられる
  • 拡張性がない例 = ゲームのカセット、一度しかデプロイできない

分散ハイパーメディア

  • 表現・制御情報はリモート側にある、サーバ側でコントロール
  • 分散ハイパーメディアの原則
    • プレゼンテーション = 表現
    • 制御情報
      • リモコンは何ができるかがクライアントに決まってる。ボタンをどう押すか
      • WEBはa tagというリンクによって制御情報が含まれている。POSTしたければ何が必要かはformタグに書いてある
      • 何ができるか、表現の中に制御情報が与えられている
  • リソース間のリンク(安全な遷移)、リソース状態の変更(安全でない遷移)を受け取る。これはサーバサイドがダイナミックに変更可能
  • クライアントを壊さずにサーバの動作を変えられないのであれば拡張性がない
    • URIが変わったらクライアント側が見れない」 NG!
    • クライアントにURIをハードコーディングしてたら拡張性がない

インターネット規模

  • 大きさのことではない
  • 無秩序なスケーラビリティ
    • 全体を理解しなくてもいい。自分が新しいページを公開しても全体が壊れることはない、独立している。
  • 独立した配備

APIはWEBではない

  • 人間がいない
  • セマンテックギャップの発生

どの特性を組み合わせるか

  • 簡単な方法は、「分散ハイパーメディア」特性を捨てることだが、「拡張性」・「インターネット規模」が喪失する。
  • 低い参入障壁 + 拡張性
    • 全てのクライアントを一度に変更する必要がある
    • 社内API といったケース
  • インターネット規模 + 低い参入障壁
  • 拡張性とインターネット規模
    • 分散ハイパーメディアを使うが、低い参入障壁は失われる
  • 人間のWeb(ユーザー視点では、ブラウザで人間が普段見るWeb)では4つの重要な要件(4つの特性)を網羅されてる
    • それに対するTed Nelsonの批判
      • 片方向のリンク、Hypertextではない
      • 「アクセスしたら初めて404とわかる」
    • Web APIの場合はどれかの特性を諦めないといけない

REST(Representational State Transfer)

Architectural Styles and the Design of Network-based Software Architecturesの内容に入っていく。

  • フィールディング制約は、6つのアーキテクチャ制約と、4つのインタフェース制約から構成される。
  • 「HTTP」は標準、これは制約
  • インタフェースについての間違いを正す
    • 統一されたHTTPメソッド(GET / POST / PUT / DELETE) という意味ではない。
    • CRUD over HTTPではない
    • URIはお化粧にすぎない。

フィールディング制約を説明するに当たり、Redhatの以下の資料を引用されながら説明されました。

www.redhat.com

REST および API設計ガイド(ca technologies)

NULL制約から始まる

統一インターフェース

統インターフェースは、4つの側面を含む。

リソースの識別

  • リソースのID = URI
  • 一つのものに多くのリソースをもたせすぎているのはBad

表現によるリソース操作

  • 表現可能ななんでも
    • ペットボトル・電気・気象条件 ...etc
  • 実態がバイト列 = ネットワークで転送可能
  • GET/POSTのセットで会話していく

自己記述的メッセージ

  • 理解するための情報
    • Content-Type, Link Header, Profileへの参照
    • Cache情報、「Cacheがいつまで有効か」はクライアントではなくサーバが知っている
  • HTTPの失敗
    • HTTP 1.0 Hostヘッダーがない
      • HTTP 1.1でHostヘッダーが入った
    • HTTP 1.1 リクエストがわからない
      • BEAR.Sundayでは、HALを利用することでこの"Bug"を解消している

ハイパーメディア制約(Hypermedia As The Engine Of Application State)

  • HATEOAS
  • アプリケーション状態・リソース状態を区別すること
  • アプリケーション状態の保持・変更はクライアント
  • クライアントは、HTTPリクエスト・レスポンス処理によって、アプリケーション状態を変更できる
  • 次のアクションは表現の中のハイパーメディアコントロールにある
    • HTMLでいうとForm
    • カートに入れる、書評を書くと行った選択肢がレスポンスの中にある

6つのアーキテクチャ制約

REST および API設計ガイド(ca technologies) を主に引用して説明されました。

6つの制約

  • クライアント・サーバー
  • ステートレス
  • キャッシュ
  • 統一インターフェース
  • レイヤ化システム
  • コード・オン・デマンド(オプション)

クライアント・サーバー

  • サービスが1つ以上の処理を行い、クライアントがこのような処理を要求するまでサービスが待機することが必要
  • Photoshopは分かれてない、一人しか使えない、クライアント・サーバーの会話がない

ステートレス

  • リクエスト間は無関係。
  • Cookieは違反 - 共有キャッシュが使えない→スケーラビリティが低下

キャッシュ

  • RESTの本質は、HypertextとCache
  • Cacheはパフォーマンス・UXに直結する
  • 自己記述的メッセージ
    • 「どれだけキャッシュできるか?」という情報が記述されている
    • クライアントはCacheについて意識しない、「3秒保持する」ということはサーバ側
  • RESTにおけるキャッシュの目的は、obtained by not using the network、ネットワークを使わないこと、これが一番の目的。
  • 失敗例、サーバーサイドのみでクライアントがキャッシュしていない 。
  • max-age
    • ex. Cache-Control: max-age=3600, Vary: Accept-Language
    • Vary Headerが大事
    • 二回目はサーバにアクセスしない。ただし、アプリケーション開発者はそれを意識しない。
    • max-age・Varyの活用により、クライアントからサーバーへのリクエスト自体がなくなった
  • 条件付きリクエスト
    • ex. If-None-Match: 3, Response: Etag :3
      • id: 3じゃなければ返して
      • 304 Not Mofified の返却
    • リクエストは発生するが、Headerのみのレスポンスとなる、Bodyがない
  • ネットワーク帯域は公共財、通信量を減らすのは金額にも影響があるし、倫理的でもある
  • Public cache
    • Cache-Control: public の設定
    • publicなものなのか、privateなものなのかが大事になる
    • public/private設定により、当該リソースが「そのまま共有できるかどうか」が明確になり、品質の向上・ドキュメンテーションにつながる
  • Cache設計
  • 高いレイテンシの「おしゃべり」API = 会話しすぎなAPI

階層化システム

  • HTTPシステムの中のコンポーネント
  • 相互に意識して、middlewareのインストールが必要とかそういうのはない
  • proxy、キャッシュサーバなど中継点を追加・削除できる

コード・オン・デマンド

  • クライアントのコードが何するかわからない -> 可視性の欠如

API設計戦略

  1. 良さそうな特性を書き留める
  2. 必要なもの、犠牲にしてもいいか考える
  3. 制約のセットを見つける
  4. プロトコル。標準のセット
  5. 繰り返す

さいごに

  • Web APIはセマンティックギャップ
  • 解決策は見えていない
  • RESTは、低い参入障壁を犠牲にして、拡張性とインターネット規模をとった
    • より賢いクライアントライブラリを使って参入証跡を下げることは可能、ただし、拡張性・インターネット規模を取り戻すことはできない
  • HTTP, URL, HTML, and Javascript

参加して感想

普段のカンファレンスでは絶対に聞けないレベルのとても興味深い話が聞けてとても勉強になりました。

個人的に面白かったのが、「人間がWebを構成する中で一番賢いコンポーネントで、APIは人間がいないセマンティックギャップが発生する」 という点で、それが故に、背景・状況によって必要な特性を選択・組み合わせていく必要があるという点でした。

設計者の考え方として面白かったのは、RESTの論文が、「制約がない状態から考える」というところから、2つのアプローチをあげているところで、どういう思考プロセスで考えているんだろうかという部分が垣間見えて良いなと思いました。

#1があれば、また参加したいなと強く思った会だったと共に、次の機会があれば、また今日よりも設計について理解が深まって議論できる自分でありたいなと感じました。

@koriymさん、開催・招待いただき誠にありがとうございました!@kseta19さん、会場の準備など誠にありがとうございました!

Laravel JP Conference 2019 にて、設計についてスピーカーの知見をたくさんいただけて感無量でした(聴講レポート)

Laravel JP Conference 2019にて聴講したセッションのレポートを書いていきます。

conference2019.laravel.jp

Laravel JP Conference

田町にて開催されました。

f:id:khigashigashi:20190216102538j:plain
入り口

エコバック・ネックトラップ・Tシャツが素敵です。

f:id:khigashigashi:20190216102616j:plain
戦利品

名札が素敵ですね!

f:id:khigashigashi:20190216102736j:plain
素敵な名札

聴講したセッションです

フレームワークとの付き合い方

@shin1x1さんより

blog.shin1x1.com

聴講メモ

  • フレームワークを使うのは「楽をするため」
  • 楽をするために
    • 理解しやすく変更しやすい
    • 利用できる便利なものは使う
    • テストを書く
    • 自動化する
    • ノウハウをチーム・コミュニティに共有、共有していくと自分にも回り回って集まってくる
  • フレームワークはHowである
    • What: アプリケーション(ドメイン、関心事、仕様)
    • How = Whatをどの技術でどう実装するか(HTTP, RDBMS, Mail, KVS...etc)
    • アプリケーションが主で、フレームワークが従
  • フレームワークは汎用的
  • SQLを書くか問題
    • 集計系の複雑なクエリをORMで実現する不毛感
    • 必要ならSQL文を書く
    • Laravelではそれ用のメソッドが用意されている
  • フレームワークのライフタイム
    • メジャーバージョンアップ対応
  • フレームワークとの適切な距離
    • 選択肢を残しておく
    • 決定を遅らせる
  • 距離のとり方
    • 独自ディレクトリを活用
    • 独自namespace
    • アプリケーションのレイヤを分ける
      • コントローラはフレームワークとの密結合になりがち
      • コントローラとアプリケーションロジックを分離
  • 事例:Laravel upgrade

感想&もやっと考えていたこと

  • フレームワークを使うモチベーションを「楽をするため」と身近な表現を使用しているのでとても共感しました。
  • フレームワークをHowと定義しているのが明確でいい
  • 集計してデータを取得したいというWhatに対して、RDBMSに対して複雑なSQLを発行することも一手段として考えて、ORMの利用などに縛られずにやっていくのがいいんだろうなとおもった。
    • MySQLからPostgreSQLに移行したいみたいなときにORMがwrapしてないところがあるみたいなのがデメリットな感じがあるけど、そもそも長くメンテナンスするシステムがその変更発生するの相当稀なんだろうなという感触。
    • パッケージシステムとかを提供している場合はORMの利点を活用したほうがいいという判断でSQL書かない選択肢もあるのかも。
  • フレームワークとの適切な距離、Howは適切に「捨てれる」状態を保ち続けることが大事だよなぁ

Ask the speakerで聞いた事

Q: CakePHPだとORMがガラッと変わるのだが変更が多い道をいくしかないのだろうか

- ORM利用している箇所を抽象にしていくとか?
    - ORM部分を抽象にしていくとかなりの数の抽象ができてテストがモックにあふれる怖さもある感じがする
  • 理想は、ORMからアプリケーションロジックを分離していくこと
  • ただし、現実解とはいえないので、後方互換性を保つためのBridgeを作るのが一つの手としてある
    • AppModel などにBridgeを定義
    • ただし、長続きはしない手法なので、とにかく動くようになったら綺麗にしていく
  • インハウスフレームワークを使ったアプリケーションをLaravelに移行する事例で使えるか考えてらっしゃること
    • アプリケーション部分を引っ剥がしていって、Howの部分を書き換えていく
    • テストは、APIレベルで書いていってそのテストが通っていればOKという確認の仕方

Q: WhatのアプリケーションレイヤとHowのフレームワーク部分のテスト

Q: アプリケーションレイヤが抽象への依存が基本となると思うが、モックがたくさんになると、モックでがんじがらめになる感覚があってこのバランス感覚はどうされてるか

  • データベースを用意してテストに必要なレコードを用意するといったコストよりかは、モックを用意するほうが辛さが少ないように感じている
  • 複雑度によるが、複雑でなければAPIレベルのテストで十分な部分もある

Q: モックに差し替える依存オブジェクトが感覚的に4つ以上超えると脳内アラートが上がる感覚がある by 川島さん

  • モックの数で考えたことはあまりなかった
  • あまりに多い場合は、クラス自体を分ける選択を考えたほうがいいかも、設計自体を見直す必要性

更に疑問を持ったところ

  • APIのテストではどのくらいの責務をテストしているのだろう、リクエストに対して期待したレスポンスが変えるというIN/OUTのみ?
    • テストの結合度をよしとするのであれば、データベース部分まで含めた広いカバレッジのテストになるかな?

Webアプリケーションが今こそ知るべき、RDBMSのパフォーマンスチューニングの勘所 ~ 未踏の速度を目指して~

soudai.hatenablog.com

聴講メモ

  • 開発速度・実行速度はどちらも大事
  • パフォーマンスの問題は、RDBMSのことが多い
  • Webサービスはクライント・インターネット・サーバーサイドと広い
  • RDBMSの基本的な仕組みを知る
  • SQL実行時
    • パーサ・リライタが構文を解析・構文木の作成
    • プランタ・オプティマイザによる最適な実行計画生成
    • エグゼキュータがクエリを実行、データ取得
  • 遅いのはエグゼキュータになる
  • 実行計画の読み方
    • EXPLAIN
  • RDBMSが苦手な実行計画になっていることが原因
    • リレーショナルモデルで表現できる情報ではない
    • 履歴やツリーは苦手
  • RDBMSが苦手じゃないけど遅い → 活用できていない
    • INDEXの活用できていない
    • 不要に大きいデータを取得してる
      • 使っていないカラムを取得してるとか(ex. TEXTの記事本文)
      • インプリシットカラムの1例
      • → クエリを扱うデータを小さくする
      • WHEREで小さく・FROMで小さく・不要なJOIN句をなくす
    • 複数回実行
      • N+1問題
      • loopでSQLを発行していたり
      • 実行するクエリを知ることが大事
    • テーブル設計
      • データベース設計は積み木
  • B+Tree INDEXの仕組み
  • テーブルスキャン
    • 1回で全行を取得
    • シーケンシャルI/O
  • INDEXがある場合
    • 人を探すときに出席簿があるイメージ
  • 設定したINDEXが効かない
    • 検索結果が多い、全体件数が少ない
    • カーディナリティの低い列
    • 曖昧な検索
    • 統計情報と実テーブルの乖離
      • バッチの大量
    • SQLパフォーマンス詳解 という本が良い
  • MySQLはNested Loop Join
    • 掛け算
    • テーブルスキャンの場合、1000行 * 1000行 = 100万行
    • INDEXがある場合 1000 + 1000*1 = 2000
  • フレームワーク依存症
  • より良い抽象化でwrappingする
  • 抽象化する箇所を忘れてはいけない

感想

  • 失敗から学ぶRDBの正しい歩き方 を買いました!
  • 抽象化されていることを理解した上で、その仕組みをどう使うのがよいかを考える
  • CQRSなどの設計概念も関連して検討すると良さそう。ORMを使う箇所とそのまま抽象化されていないSQLを利用するか

疑問

  • 積み木になってるテーブル設計とマジカルなテーブル設計の違いと避け方
  • マジカル設計に追加された丸いテーブル設計の例どういうイメージだろう
  • → あとでSQLアンチパターンとか復習しよう

Laravelで学ぶ、ウェブアプリケーションチューニングの基本

聴講メモ

  • 「遅い」とは?「遅い」は主観、曖昧なため改善できない
  • コンテキスト・数値の説明によって具体的な状況が浮き彫りになる
  • 「推測するな計測せよ」
  • ウェブアプリケーション全体像を見る
    • 自分の領域(ウェブアプリ)の狭さを知る
    • アンコントローラブルな領域があることを知る
  • パフォーマンスを科学する
    • レイテンシー
      • 待つためにかかった時間を計測した値
        • ex. HTTPリクエストからレスポンスまで
    • ウェブアプリ以外の遅さ(大陸間・速度制限・共有LAN)
  • ウェブアプリの責任
    • 大陸間の遅さは、ウェブアプリでは改善できない、CDN等の対策
    • ウェブサービスの「レスポンスタイム」で正確にすることができる
  • Webサーバメトリクス
    • ウェブサーバの「遅さ」が本当にウェブアプリのせいなのか
    • メモリ使用量・CPU使用率・ディスクI/O ...etc
    • sysstat package, CloudWatch, Mackarel, netdata ...etc
    • 継続的にデータをとって傾向を見る
  • Webアプリから原因を探す
    • レスポンスタイムが遅いURLを探す
    • alp ...etc
    • New RelicなどのWeb Tool
  • プロファイリングする
  • 改善ループを回す
  • よくある問題と対処
    • HTTPのAPIコール
      • 1コール1秒くらい遅くなると思うくらい
      • 更新頻度によってはCache
      • 自前APIであれば専用APIを用意
    • メール送信
    • Slack通知
      • 同期的に処理すると遅くなる
      • Queueを使おう
    • SQLクエリ実行
      • 単発なクエリ遅い場合
      • N+1クエリ
    • 計算量がムダに多い
  • サーバ・インフラを支える技術
    • 第一章を読もう

感想

  • 普段Mackarelだけど、昔sarコマンド実行してたことあったなと懐かしくなった
  • ウェブアプリ全体を見渡してパフォーマンスを見るというのがすごくわかりやすかった。
  • よくある問題と対処ありがたい情報、slack通知を非同期はぐさっと刺さった。
  • パフォーマンスチューニングをやる思考プロセスが言語化されてて、この進め方で一度やってみようと思う内容でした。

抽象化って何?

blog.hidenorigoto.com

聴講メモ

  • 抽象化 Abstraction
  • 設計の問題はソースコードの中にこそある
  • 数独」アプリの「正解チェック機能」の実装を担当するシチューエーションを想定
  • 依存関係逆転の原則の使い所
    • CheckableMatrixInterfaceを作ったが、、、?
    • なにかが間違ってる...
  • 現実世界の抽象
    • 抽象化とは
      • 抽象 = ある部分だけを取り出すこと
      • 捨象 = 取り出した結果捨てられるもの
    • 抽象のハシゴ
    • 抽象化における変化
      • 特徴量が少なくなり対象の数が多くなる
    • 抽象レベルがおかしい文
      • 別の抽象レベルが混在するとおかしくなる
  • プログラミングにおける抽象
    • 道具: プログラミング言語・構文・語彙
    • 数独アプリ」を表現するための
    • 扱っている問題や概念を抽象化すること
    • 達成するために機能を用いる(Interface, Abstract)
  • 抽象の指針
    • 適切な命名
    • 抽象度の統一
    • 狭い範囲
  • CheckableMatrixInterfaceはどうだった?
    • 適切な名前か?
      • ChackableなtoArrayとは
    • 抽象度の統一
      • toArray()、arrayを使う前提?
    • 狭い範囲
      • 一つだけ
      • Checker -> check: CheckerとCheckableMatrixInterfaceの関係では狭い範囲になっていない
      • Matrix -> toArray: せまくなってる?
  • 依存関係の本質を見極める
    • 本質に迫っていく
    • Checkerは最低限何があれば責務が果たせる?
      • Checkerは数字の列を扱う
        • NumberCollectionから数字の列を受け取る形
        • checkNumbersのコードのみになる
      • 数字の列生成
        • アダプターで吸収、データの形を「数字の列」に変換
  • Afterの評価
    • MatrixからNumberCollectionになり狭い範囲になった

感想

  • プログラマとしてのシチュエーションから入るのが話に入りやすくて、さすがわかりやすい発表だなと思いました。発表の仕方参考にさせてもらおう。
  • 重要なポイントじゃないけど、array_intersect知らなかったのでほーとなった。
  • 抽象とはなにかと、実現するための手段(Interfaceなど)がごっちゃになってる自分の理解が不足している点を気がつけて「なるほど!」でした。

Ask the speakderで聞いたこと

Q: 狭い範囲について改めて聞く

  • 抽象のレベルが上がるほど特徴量が少なくなる
    • 目の前のペイジ → 仔牛
    • 仔牛 では、「乳が絞れる」という機能を持った、細かい特徴を捨象したものが見つかるかも
  • 目の前のものだけを見ると、目の前のものに引っ張られてしまう
  • 複数同じようなものが出現した際に抽象を見つけるきっかけになる

Q: 設計について学んだ経緯

  • 設計はまだ形式知的になりきれてない部分
  • 設計の師匠を見つける
  • 設計のベテランがいる設計コミュニティ
  • 渡辺 幸三さんの考え方、データモデル・業務モデル・機能モデルの3要素で考える手法
  • 帳簿の世界は、MicroService的に世界が切られている
    • 現実世界を観察していくことは、非常に有用

Q: 設計に興味を持ってもらうには?

  • (筆者個人的に)社内でオブジェクト指向設計勉強会をやっていて、どの業界から来たかで設計に対する興味の度合いが変わる気がする
  • システム性質上、データが重要になるとデータモデリングなどに対しての興味が強くなることもあったり、確かにバックボーンによって変わるのはある

SimpleとEasyは違う

聴講できなかったのですがTLで流れてきてすごいしっくり言語化されてて参考になりました。 Simpleは客観でEasyは主観という言葉がすごい刺さりました。

カンファレンスを通して

今回はスピーカー・スポンサー・スタッフなしの完全聴講者としての参加だったけど、がっつりスピーカーの方々の話を聞けて、もやもや悩んでいたことを言語化していただいてとても勉強になりました。 Ask the speakderで直接質問できる場があるのもとても良かったです! カンファレンス行くと、新しく興味を持って深めたい分野が出てくるのでやっぱりいいですね。パフォーマンスチューニング系の話についてもPHP勉強会でLTくらいできる内容を一度ガッツリ時間をとって実践したいと思います!

とても明日から意識・実践できることが増えてとても楽しいカンファレンスでした!スタッフの皆様運営ありがとうございました!

Go 1.12 Release Party attendee report

gocon.connpass.com に参加した際の発表とその際のtwitterのTLから参考になったことを雑にまとめてます。

Go 1.12

tip.golang.org

Go1.12 changes

Creating a lint tool with analysis

Go Modules

other references

speakerdeck.com

Goならわかるシステムプログラミング改訂のお知らせ

Go language serverを理解する

Go 1.12 Release Party attendee report

gocon.connpass.com に参加した際の発表とその際のtwitterのTLから参考になったことを雑にまとめてます。

Go 1.12

tip.golang.org

Go1.12 changes

Creating a lint tool with analysis

Go Modules

  • presented by @budougumi0617
  • previous version manegement
    • go get
    • 3rd party tool (dep, glide)
  • semantic versioning
  • GOPATH mode
    • same as older than 1.10
    • 標準pkg以外GOPATH以下で管理
  • module-aware mode
  • go mod command
    • test case(cmd/go/testdata/script)から使い方・挙動が理解できる
  • go modのバイナリは、$GOPATH/pkg/mod/以下にcache

other references

speakerdeck.com

2018年を振り返り2019年の目標を見据える

自分の心境を記録する自己満足的な振り返り。

2018年の振り返り

2017年10月に現職のBASE株式会社に転職してきてからだいたい1年ちょっと経過。「PHPカンファレンスのメインホールで登壇できるようになりたい」という目標を採用面談時にマネージャー氏に話していた私にとって、その目標に少し近づけた年だった。

発表駆動開発を一年間実践してきて今 #phpcon の際に今年1年の発表回数をカウントしたところ20回あったので、だいたい1ヶ月に1回以上はコンスタントに何かしらをアウトプットできた。

個人的には、PHPカンファレンス2018にて、PHPバージョンアップと決済リプレイスを支えたユニットテスト #phpconというタイトルで25分セッション発表ができたことは、やってきたことが目標に向けて近づいた感じがあった。

また、より低レイヤに興味があった私にとって、チャレンジしたかったGo言語での開発にも趣味から業務までつなげることができ、Go Conference 2018 Autumnでの、LT2本発表として知見をアウトプットできた。

devblog.thebase.in

業務的にも、既存・新規サービスの機能改修/開発・言語・フレームワークのバージョンアップを経験し、それ以外のテックブログへの寄稿・カンファレンスへのスポンサーの機会を増やすことができたりと、幅広いチャレンジができた。

アウトプットに対する捉え方の変化

「セッション登壇できるくらいになれば強いエンジニアになれた」と自分でも自信がつくはずと思い1年やってみたが、むしろ逆だった。 登壇などでアウトプットする機会が増えることによって、より強い人達とあう機会ができたり、発表をしたことによって改めて分かる「強い」人たちの話の深みを実感し、まだまだ先がありすぎると感じ続ける1年だった。

また、「はてぶがつく」などいわゆるバズることと、個人の技術力が比例するわけでは無いことも感じ、あくまで技術力向上の指標とする場合は、「バズる」ことに対して固執せずアウトプットすることが重要だなと感じた。

ただ、やはりアウトプットしてきたことによって、開かれた機会・得られた技術的知見があり、来年もしっかり継続したい。

2019年の目標

大方針

2018年は、「今ある仕組みの中で時には愚直にどのように取り組みことが有効か」という観点のアウトプットが多かった。 2019年は、「そもそもの課題をどう仕組みを作って解決していくか」というステップに進みたい。

次の関心事

今年はユニットテスト周りで様々アウトプットしてきたが、次の深みとして「アプリケーション設計」分野に対して洞察を深めていきたい。

アプリケーション設計をやっていきするにあたり、Go・PHPといったサーバーサイド外の技術スタックが大きく影響するため、フロントエンド・インフラに関しても一定の理解とアウトプットを出していく。特にインフラに関しては幸い業務でECS/Fargateを触っていたり少しずつ、理解を深める取っ掛かりができつつあるので、少し遠いフックかもしれないがインフラの「基礎的」な理解を深めたい。

具体的な目標

具体的なことが語れる部分だけ明示的に目標として掲げる

  • Go系カンファレンスでのセッション登壇
    • Go Conference 2018 Autumnでは、LTにとどまったので、来年はがっつりセッションとしてトーク応募を出せるだけの深みを持ちたい。
  • PHP系カンファレンスでのロングセッション登壇
    • 2018年ショートセッションでの登壇の目標は達成できたので、更に体系的で深みのあるインプットをして、ロングセッションでの登壇をしていきたい。
  • 合計発表時間300分
    • 20分相当を15回すれば達成できる数字として300という数字を設定した。
  • OSSを3個以上公開する
    • 大方針として、「そもそもの課題をどう仕組みを作って解決していくか」というものを目指すため、第一歩としてどんなものでもいいのでちゃんとOSSとしての訂正をもってツールなどを作成・公開していく。

まとめてみて

特に誰に読まれるであろうなどを一切考えずに書いたので、裏付け情報や根底の背景などはすっ飛ばして書いた結果、改めて関心の濃淡を再確認した。
ここで書いていないこととして、「何を実現したいか」ということに関しては言及していない。それは、「手がけているサービスをどうしていきたいか」などが挙げられるであろう。ただ確かなことは、「サービスをもっと良くしたい」などの実現に対するモチベーションはたしかに持っていて、だからこそ、実現する意義があると感じる現職に在籍していることだ。
個人として、「実現できたら世界が良くなる」ということに対して実現できる能力がどれだけあるかということに関して職業エンジニアの価値があると根底に思っているが、価値あるものであるために現時点の関心は眼の前に映る「より良さそうな自己になるにはどうすればよいか」に集中している。
他人のスタンス・価値観を理解する際にも、何により関心を集中させているのかは有用な観点ではないかと思った。

というまとまらない終わり方をして、平成最後の振り返りエントリを納める。

「PHPフレームワーク Laravel Webアプリケーション開発」を読み終えた感想

2018/9/26に発売された、書籍「PHPフレームワーク Laravel Webアプリケーション開発」を読み終えましたので、感想を書いていきます。

PHPフレームワーク Laravel Webアプリケーション開発」とは

f:id:khigashigashi:20181007232928j:plain https://www.amazon.co.jp/gp/product/4802611846

こちらは、PHP界隈ではとても有名な@ex_takezawaさん・@kurikazuさん・@shin1x1さん・@omoonさんが執筆し2018年9月26日に発売されたものになります。 書籍の概要については、@shin1x1さんのブログにてご紹介されている内容を参照させていただきます。

blog.shin1x1.com

Laravel 5.5(LTS) に対応した本です。Laravel リファレンス のようにフレームワークの機能解説はもちろん含まれているのですが、機能を紹介するというより、実際にありそうなユースケースでどのように利用するかといった視点で書かれており、開発現場で Laravel をより活用したい向けの内容になっています。目次を見ると、実践的な内容が多く含まれていることが分かるでしょう。

読み始める前のモチベーション

今回の本を手にとったモチベーションとしては次のような物がありました。

  • 普段、CakePHPを業務で触っているが、Laravel自体を改めてがっつり触りたい
  • サービスコンテナがどのような実装になっているかなどLaravel内部の実装を知りたい
  • レイヤードアーキテクチャなどアーキテクチャについての実践例を知りたい

読んだ結果

控えめに言って大変勉強になった内容でした。具体的には下記の点がとても良かったです。

Laravelの内部実装・構造から学ぶ

序盤の章にて、Laravelの内部実装を見ながら、サービスコンテナの仕組みやMVCADRといったアーキテクチャについて学べる内容になっていました。自分の中で言語化されていなった点についてLaravelのコードにて示される点がよかったです。

テスト駆動開発の実践例

最終章にて、顧客訪問記録アプリケーションを想定したバックエンドAPIをテスト駆動で実装してく章があります。
API実装といった業務で実践的な例でのテスト駆動開発についてやり方を見ることができたのは、普段自分が実践してみている方法と照らし合わせつつ見れたのでとても参考になりました。

読み方

この著書は、合計531ページありとてもボリューミーだったので、私は次の読み方で進めました。

  • 第一部は、全部しっかり読み込み・写経する
  • 第二部は、部分的に詳細の仕様の話になるので、全体感を抑えながら第一部からつながる部分のみ写経する
  • 第三部は、テスト駆動開発での実践で第一部・第二部の知識の総集編として抑えられるのでガッツリ写経する

写経レポジトリ

今回写経していったレポジトリはgithub上にcommitしながらやっていました。chapter終了タイミングごとにcommitをしてrelease labelを付ける方法でやっています。

github.com

最後に

PHPフレームワーク Laravel Webアプリケーション開発」は、普段Laravelを使っていない身でも理解しやすく、Laravelに限らずアプリケーション設計・アーキテクチャなど非常に汎用的な知識に関して実践できる内容になっていました。

まだ、手に取られていない方は、ぜひ一度手に取るといいと思います!

Amazon CAPTCHA

(サインほしい。。。)

ドメイン駆動設計についてpospomeさんの話を聞いた | Gopher道場課外学習Ⅰ参加ログ

Gopher道場卒業生向けのイベントとして、ドメイン駆動設計について@pospomeさんの話を聞かせていただきました。

mercari.connpass.com

その際に話されていた内容についてざっとメモを残させていただきます。

ドメイン駆動設計とは

  • ドメイン
    • = 問題領域
    • ソフトウェアを適用する業務や関心事
    • ドメイン = 業務
  • 例:弥生会計
  • 業務で設計を駆動すること = ドメイン駆動設計

    merit of ddd

  • 既存の業務駆動ではない設計手法
    • DOA(データ中心アプローチ)
      • テーブル構造がModelになるMVCフレームワークではDOAになりがち
      • DBにデータを格納することを前提としている
      • -> DBの特性・目的に合わせたデータ設計になる
        • 特性:redis・RDBMS等でデータ設計が異なる
        • 目的:頻度・データ量によって異なる
      • DOAによる設計はプログラミングに対して最適かどうかはそうとは言えない、可読性の低下の可能性
        • 業務上存在する概念をコード上で扱えない
        • ex: UserAcountテーブルの構造体とプロフィール変更
          • プロフィール変更についてどのカラムがプロフィールなの?ということに関して表現できていない
          • UserProfile structを作って何がプロフィールかをコード上で表現する
        • ex: Boss
          • rankをもっている、big: 大ボス、middle: 中ボス
          • 大ボスのみAttack()できるという仕様をどう表現するか、Attackはいつ発動するのか(中ボスからAttackを呼んだときになにもしないという事がわからない。)
          • BigBoss / MiddleBossでそもそも分けてしまう。別々のモデルにすることでそれぞれ何ができるかが明確になる
  • DOAで設計したデータ構造をそのままプログラミングで扱うのが問題
  • 可読性が下がる根本原因 = 業務とコードの乖離
    • 問題:業務の理解・コードの理解、両方を理解しないといけない
      • ex: type, status, flg といった謎カラム
  • DDDではデータ構造をそのままプログラミングで利用しない、プログラミングに適したデータ構造を利用する
    • -> 業務とコードの乖離を可能な限り少なくし可読性を分ける
    • -> 業務を理解 -> コードも理解できる
    • -> 実装詳細に踏み込みやすいコードになる
  • 業務を反映したデータ構造 + 振る舞い => 業務駆動開発(DDD(

何をすればDDDになるのか

  • 実装がゴール、実装のための分析・設計
  • 分析
    • 業務をコードに落とし込めるように分析する
    • 実装がゴール、そのゴールを達成するための分析
  • 設計
    • 分析結果をコードに落とし込むための設計
  • 実装
    • 実装する
  • 各フェーズに対応したテクニックが存在する
    • レイヤ構造は実装のための設計、分析・設計・実装のための一つの要素に過ぎない。
    • リポジトリパターンは実装テクニック、同上でただの一つの要素に過ぎない
  • 戦略(分析&設計)・戦術とDDDは分けている
  • 戦略(分析&設計)が大事
  • 戦術のみ適用する = 軽量DDD、アンチパターン
    • ex. レイヤ構造・リポジトリパターンを適用したよ = 軽量DDD
    • 分析をしていない、業務とコードに乖離が生じる
  • 分析→設計→実装を通して初めてDDDになる

demerit of ddd

  • 学習コスト
  • 分析コスト
  • 実際可読性が上がるかはわからない、分析結果によっては可読性が上がらない可能性がある
  • モデルとDBのデータ構造が異なる、モデルとDBがほぼ同一である前提であるRailsのようなフレームワークを使っている場合の実装の手間

解決できないこと

  • 業務の複雑さに伴うコードの複雑さは解決できない
    • そもそも業務が複雑であれば、それをそのまま反映する
  • 実装者の設計スキルが低いと可読性落ちる

necessity of DDD

DDD不要な例

  • DBのデータ構造がプログラミングに適している場合
    • ex: 単一概念のCRUD
    • DDD不要
  • 業務とコードのか入が問題にならない
    • 保守しない、業務が単純

軽量DDD

  • DDDではないが、単なる実装パターン詰合せとしては優秀

GoとDDDの相性

GoでDDDは相性

  • ORM問題 Java > Go
    • モデルとデータベースのマッピング
    • ORMでマッピングを任せられると
    • インピナンスミスマッチを埋められるか
      • Goにはない、というか他の言語にもあまりない、Java特有かもしれない
  • アノテーションベースのAOP Java > Go
  • 情報量 Java/Scala > Go
    • Javaの実践例はPHP/Rubyでも参考になる
    • Goはすこし言語仕様が異なるので実践した情報量が少ない

Q&A

  • メルカリで使っているか
    • 現状使っていない、ビジネススピードなどによりWeb系で導入していない
  • microserviceとの相性
    • 相性はいいっちゃいい、業界付けられたコンテキストのテクニックは相性がいい
    • ただし、DDDとマイクロサービスの設計の親和性は要件による。
      • データ構造がプログラミングに適しているかどうか。
    • 密結合を分割 -> 分断されたモノリス
  • マイクロサービス間で重複したコードを書く問題
    • マイクロサービスをやるならコードの重複を受け入れるのが前提のスタンスと必要になる
    • その上で共有したい場合は、ライブラリ化・サブモジュール化というアプローチもあるが、各サービスで必要なメソッド・フィールドを足していったりするとカオスになる。
    • サービスごとに必要とすることが異なるケースが多い。
  • コードが成果物 = コードを見ることで業務を知ることができる
    • DDDの目的は可読性の高いコードを書くこと
  • いい設計を行うためのアプローチ
    • 作る対象の業務を知る必要がある
    • 業務の理解度を上げることでコードの質が上がる
    • ただし、設計の引き出しが多い人が勝つ、設計スキルが低いとそもそも可読性が下がる
    • たくさん書いてたくさん失敗すること
    • なれている自分の設計パターンと違うアプローチを取り入れてみる、いつものパターンは人から見たら良くないかもしれない。

最後に

ドメイン駆動設計について、何をやったら「ドメイン駆動設計」なの?とふわふわしていたのですが、「業務(ドメイン)で設計を駆動する」がどういうことなのか解説いただいたのがとても参考になりました。

次回はGCPについてのお話が聞けるということでとても楽しみです! mercari.connpass.com