Software engineering from east direction

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

golang.tokyoの「文Go」に「費用対効果の高いユニットテストを実現するためのGoの基礎技法」を寄稿しました #技術書典

TL;DR

  • 技術書典6のgolang.tokyoサークルが出ます。
  • 「費用対効果の高いユニットテストを実現するためのGoの基礎技法」を寄稿しました。

技術書典6に出版する書籍に寄稿

この度、2019年4月14日に開催する技術書典6に参加するgolang.tokyoの新刊に「費用対効果の高いユニットテストを実現するためのGoの基礎技法」というタイトルで寄稿しました。

techbookfest.org

golang.tokyo「文Go」

f:id:khigashigashi:20190411220059p:plain
文Go

Go界隈の方であれば一度は目にしたことのある方々がそれぞれめちゃめちゃ濃い内容を書いてます。(このラインナップに自分がいるのが恐縮すぎるw)

計136ページの大作になっているのでぜひ当日「け27」にお越しください!(レビューしていて勉強になりまくった内容なのですごくおすすめです)

寄稿内容「費用対効果の高いユニットテストを実現するためのGoの基礎技法」

私が寄稿した内容は、ユニットテストの考え方とGoの基礎についてです。私は、ユニットテストに関心があり、所属企業のブログにもGoのAPI開発現場におけるユニットテストTipsにて、ユニットテストに関する現場の実践を共有したりしてます。最近は、基礎となる考え方に興味があり、PHPerKaigi 2019というカンファレンスでは「質」のいいユニットテストを書くためのプラクティスという内容で、ユニットテストの考え方について発表していました。今回寄稿した内容も、そのような考え方とアプローチに着目したものです。
Goは、アサーションが提供されていない点など、他の言語と比較して特徴的な点がいくつかあります。しかし、「Goが何を考えてそうしているのか」・「その考え方は現場でのユニットテストにどのような利点をもたらすのか」という基礎的な点を抑えると、応用的な取り組みも一貫した考えをもって実践できると考えています。

まとめ

ぜひ、「け27 golang.tokyo」まで!

techbookfest.org

2019年の目標達成確認と振り返り

超絶フライングで振り返り続けるエントリー、目標に対する進捗・振り返りが更新されていきます。

khigashigashi.hatenablog.com

年初立てた目標の達成状況

目標 現在 備考
PHP系カンファレンスでのロングセッション登壇 Clear PHPerKaigi2019にて30分(longer)
Go系カンファレンスでのセッション登壇 Clear Go Conference Tokyo 2019 Springで20分
合計発表時間300分 Clear(367分)
OSSを3個以上公開する Clear(3)

(2019/3/31時点更新)

登壇記録

count: 25

日付 イベント名 タイトル Type
2019/12/01 Japan PHP Conference 2019 知見のない技術スタックをプロダクション導入するエンジニアの導入戦略 Session(25min)
2019/11/09 CakeFest 2019 Test-Driven Development to avoid test painful Session(30min)
2019/10/12 PHPカンファレンス沖縄2019 「PHPにおける独自例外設計を考える 懇親会LT(5min)
2019/10/12 PHPカンファレンス沖縄2019 「割れ窓」を増やさないためのコード設計 本編LT(5min)
2019/10/11 PHPカンファレンス沖縄2019 前夜祭 デザインパターンを出自から深く理解する Session(15min)
2019/9/25 第142回PHP勉強会 ブランコの比喩はどこから来たのか Session(20min)
2019/9/21 PHPカンファレンス北海道2019 自作して理解するxUnit LT(5min)
2019/9/16 PyCon JP 2019 Pythonを使った APIサーバー開発を始める際に 整備したCIとテスト機構 Session(15min)
2019/8/26 GopherCon 2019 報告会 by Gopher道場 GopherCon 2019 Report Talk Session*(15min)
2019/7/27 GopherCon 2019 Building API Server-side Architecture for beginners LT(7min)
2019/7/13 Go Conference Fukuoka 2019 Cost-effective Go Unit Test thinking and practices Session(20min)
2019/6/29 PHPカンファレンス福岡2019 ユニットテストの現場の問題を原則に立ち返って考える Session(30min)
2019/5/28 CircleCI ユーザーコミュニティミートアップ #4 CircleCI Go Code Inspection LT(5min)
2019/5/27 Go(Un)Conference(Goあんこ)LT大会 6kg Go API Validation error handling LT(10min)
2019/5/18 Go Conference Tokyo 2019 Spring Design considerations for Container based Go application Session(20min)
2019/5/8 表参道Web勉強会 3 TypeScriptで入門するGenerics LT(5min)
2019/4/25 突撃!!隣のアーキテクチャ GoでのAPI開発現場のアーキテクチャ実装事例 LT(5min)
2019/3/29 PHPer Kaigi 2019 「質」のいいユニットテストを書くためのプラクティス Session(30min)
2019/3/27 Docker Meetup Tokyo #29 (Docker Bday #6) Container based application Design Real Practices Session(15min)
2019/3/20 【書籍発売記念】Connehito Marché vol.5 〜PHP市〜 xUnit Test Patternsから学ぶテストアンチパターン LT(10min)
2019/3/1 Mackerel Meetup #13 Health endpoint pattern as application monitoring LT(5min)
2019/2/27 第135回 PHP勉強会@東京 ユニットテスト初心者を脱するために身につけたいN個のこと LT(5min)
2019/2/26 Docker Meetup Tokyo #28 Container-based Application Design Reference and Practice LT(10min)
2019/1/30 第134回 PHP勉強会@東京 Steadily developing CakePHP 4.0 Session(20min)
2019/1/26 PHPカンファレンス仙台2019 テストが辛いを解決するテスト駆動開発のアプローチ Session(30min)

各Q振り返り

3Q (2019/7~2019/9)

まずこのQで一番印象深いトピックといえば、アメリカで開催されたGopherCon 2019でLT(7min)ですが初めて登壇したことでした(GopherCon 2019に参加、海外カンファレンスでLT登壇した経験を振り返る)。自分が関われるフィールドが国外にまで伸ばせるんだと少しでも思えたのでいい経験でした。それなりの人の数の前で英語スピーチしたことは実は大学の頃にもしたことはあったのですが、英語を母国語とするアメリカで現地の人達が大半を占める場所でしゃべるのは初めて非常に緊張しました。直前2週間は「なぜ登壇しようと思ってしまったのか・・・」などと暗い気持ちになったのです が無事終えれました。来年はさらに高度な内容をレベルアップさせたプレゼンテーションで国外に喋りに行きたいです。いやぁサンディエゴ天気良くてよかったなぁ。

次に嬉しかったのは、PyConJP 2019に出たことです(PyCon JP 2019に登壇、PythonでのCIとテストの話をしました)。PyCon JPは私が初めて参加したカンファレンスでその時の登壇者に憧れたのが原体験になり、今様々なカンファレンスに登壇者として参加しに行ってることに繋がっているので、数年ぶりに点と点が繋がってエモい気持ちになりました(ブログでもそれなりにいい反応を頂いていたのですごく安堵しました)

一方でこのQは、福岡・アメリカ・北海道と遠征で物理的に社にいない時間が増え、なんとか稼働をあげて人並みの事業貢献を保ったという期間になりました。「人並み以上の事業貢献をしながら外部貢献をしている」という状況を保ちたい気持ちはあるので遠征を含む外部登壇については取捨選択が必要かもなぁという課題感を感じました。

次のQは、2019年を締めることになるので、人並み以上の事業貢献をやりつつ、CakeFest 2019での英語スピーチの準備をしていこうと思います。また、ブランコの比喩はどこから来たのかでも20分熱く話させていただいたのですが、建築設計に強い興味があるので、2020年皆様の前でなにか知見となる考えが話せるようにこちらの理解も深めていきます。

では、また4Qで。

2Q (2019/4~2019/6)

golangtokyo への寄稿という形で人生初の技術書執筆デビューできました。今年中に技術書典などで技術同人誌を書きたいと目標としていたので達成感です。PHPerKaigiの登壇から間髪入れずに締め切りが来た形なので相当しんどかったんですが、相当自分の中の言語化が進んだので非常にいい機会でした。また、尊敬しているGopherの方々と技術書執筆という形で協働できたのが非常にエキサイティングな時間でした。もっとこういう楽しい時間を増やしたいのでOSS活動に本腰入れて取り組みます。

また、今年目標にしてたGo Conferenceでのセッション登壇も達成できたので良かったです。しかし、まだまだGopherとしてまだまだなので引き続き精進です。

仕事としても2Qの目標をしっかり達成できたので良かったです。各種諸々があり仕事でPythonを扱うようになり、JetBrainsのEditorを3言語分switchしながら開発できるようになりました、はい。

PHPカンファレンス福岡では、PHPerKaigiのときには内容に含めることができなかったモックの話ができたのと、その発表するために16冊くらい関連書籍を読み漁ってだいぶユニットテストソフトウェアテストという分野の深さを実感する事ができました。

事業に対する貢献とコミュニティに対する貢献のバランスが云々ともやもやしていたのですが、個人としてやりたいことをやっていった先に組織や事業貢献があるようになっていれば結果的にいいのではと改めて思い直すなどしたので、来Qもいろいろなチャレンジをしていきます(というかもういろいろチャレンジの予定があるのでやっていくのみ)

1Q (2019/1~2019/3)

仕事は昨年リリースしたサービスの運用基盤系の整備・機能拡張についての目標を無事達成でき成果の出せた3ヶ月になったはず。

それ以外の関心事の中心は、3ヶ月間ずっと、PHPer Kaigi 2019トーク「質」のいいユニットテストを書くためのプラクティス』の論理をどうやって頭の中で整理・構成するかに集中していました。普段、現場で言葉として発せられる「テストの質」について「その本質・意味はなんなんだ」というなにやら壮大なテーマをモヤモヤ考えていました。途中のいくつかのカンファレンス・勉強会・ブログでのアウトプットを通じて少しずつ考えを整理していって、今回の着地点に落ち着いたことに達成感を感じています。
ただし、同時に多大なる挫折感も感じていて、まだまだ自分では言語化できていないことが今回の30分の発表で入れた内容の何百倍もある状態です。この分野はまだまだやっていかないといけないことが多いですね。

そのほか、達成感を感じているのはDocker界隈など少しずつ下のレイヤでのアウトプットができるようになってきたことです。Container based application Design Real Practicesという発表を、Docker Meetup Tokyo #29 (Docker Bday #6)にお邪魔してさせていただいたりと、一介のサーバーサイドエンジニアの視点を入り口としてでも、自分が見える世界を少し広げられたことは嬉しく思います。

また、個人的にとってチャレンジングだったことは、アメリカ・サンディエゴで開催されるGopher Conference 2019や、今年日本で開催されるCakeFestへのセッショントーク応募ですね。英語ぺらぺらで自信があるわけでもないですが思い切って25分/30分のセッション応募したのは勇気がいりましたが行動してよかったと今では思っています。Gopher Conferenceのほうは残念ながら落選でしたので現在LT応募を量産しています。

しかし、マネージャー氏に高々と宣言した「今年はOSS作っていきます!」という言葉は今Q虚しくも「有言不実行」に終わってしまったので、来Qはやっていきします。

総括して、今Qも後悔なく生ききれたなという満足感です。

OSS

Contributing

細かいのは省いて主要なところだけ

日付 OSS 内容
2019/10/21 cakephp/doc CakePHP3.9移行ガイド翻訳
2019/6/30 cakephp/doc CakePHP3.8移行ガイドページ翻訳
2019/1/18 cakephp/doc 3.7移行ガイドページの翻訳

Creating

released repository 内容
2019/12/19 hgsgtk/health-endpoint Health endpoint patternを実装するサンプルです
2019/9/20 hgsgtk/mpunit Mini PHP xUnit Testing Framework、PHPカンファレンス北海道2019で発表
2019/4/28 hgsgtk/jsoncmp JSON値の比較ライブラリ、OSSとしての体裁を整えた最初のrepository

技術書執筆

出版日 カテゴリ 内容
2019/12/5 技術評論社 みんなのPHP 現場で役立つ最新ノウハウ!
2019/4/14 技術書典6 golang.tokyoの「文Go」に「費用対効果の高いユニットテストを実現するためのGoの基礎技法」を寄稿しました #技術書典

公開ブログエントリ

※ イベントレポートは除く

所属企業寄稿

公開日 カテゴリ タイトル
2019/12/04 AWS Amazon Auroraのカスタムエンドポイントでのフェールオーバーを想定した設定
2019/11/11 英語 【英語スピーチの振り返り】日本で初開催のCakeFest 2019での登壇、スポンサーしました
2019/5/22 登壇 Go Conference Tokyo 2019 Spring にて行った発表内容の作り方 #gocon
2019/3/6 監視 アプリケーション監視のパターン「Health エンドポイントパターン」を実践する | 書籍『入門 監視 ―モダンなモニタリングのためのデザインパターン』を読んで
2019/1/16 AWS ECS(Fargate)でコンテナアプリケーションを動かすための設定情報の扱い方

エントリ

公開日 カテゴリ タイトル
2019/12/31 心理 年末にちょうどいい「やり抜く人の9つの習慣」と「やる気が上がる8つのスイッチ」
2019/12/30 設計 プレゼンテーション・パターンという認識のメガネ | 書評「プレゼンテーション・パターン: 創造を誘発する表現のヒント」
2019/12/30 設計 パターン・ランゲージを分野を超えた流れから捉える | 書評「パターン・ランゲージ: 創造的な未来をつくるための言語」
2019/12/24 Go mackerel-container-agentから学ぶGoにおけるリトライ実装
2019/12/19 Docker Docker開発環境のDBにReadOnlyユーザーを作り書き込みバグを検知する
2019/12/18 PHP CakePHPのドキュメント翻訳は英語学習とフレームワークのキャッチアップにつながる
2019/12/7 Go [Go] constant x.x truncated to integerはなぜおきるのか
2019/12/1 PHP 来たるCakePHP 4.0 を知ろう
2019/10/29 書評 ジェームズ・W・ヤング「アイデアの作り方」から考える登壇などでのアウトプット
2019/9/12 書評 書評: パターン、Wiki、XP ~時を超えた創造の原則 がすごく面白かった
2019/8/8 Go go-playground/validatorを用いてカスタムバリデーションルールを作る方法 on Qiita
2019/7/6 学び 外部イベント登壇しがち属性が考える登壇の使い方
2019/4/27 Go GoLandでgoldenファイルを用いたユニットテストを書く #golang
2019/4/17 PHP PHPerKaigi 2019 の「PHPでJVMに入門する」を聞いて
2019/3/21 Unit Test xUnit Test Patternsから学ぶユニットテストについて目指すべき6つのゴール on Qiita
2019/3/17 Unit Test xUnit Test Patternsから学ぶ12個のユニットテストの原則 on Qiita
2019/3/9 Go Goのテーブル駆動テストをちょっと見やすくする on Medium
2019/3/8 PHP PHPの空配列をJSONの空オブジェクトとしてエンコードしたい時 on Qiita

「第三回ボトムアップドメイン駆動設計」でDDD(主に軽量DDD)について聞いてきた | 聴講レポート

「第三回ボトムアップドメイン駆動設計」という成瀬さん(@nrslib)さんによる、ドメイン駆動設計のイベントに参加してきました。 曖昧な理解でふわふわしていた箇所が、かなりつながった感覚があって大変ありがたい会でした。

nrs-seminar.connpass.com

nrslib.com

公開していただいている資料

イベント中に話されていた資料はtwitterでシェアしていただいていました。

資料内での補足

ドメインとは

集約の範囲

変更はトランザクションの単位という話をよく聞くが逆。変更の単位だから結果、トランザクションの単位になる

当日の質問

できるならやったほうがいいが、チームの反発具合によるところがある。ただ、有益だと思える箇所ならやったほうがいい。 ブログの本文とかただのIDとか別にそこまでやらなくてもいいねっていう箇所は勘所。

実際に入れていくなら、今回の例の「製品コード」とか複数組み合わせがあってクラスにしたほうがいいといった、目に見えてメリットを感じやすいところからやる

アプリケーションサービスをどういう単位?

非常に難しい問題。メソッド一つ一つクラスにする。「サークルのユーザーを取る」ときにサークルサービス?ユーザーサービス?そもそもクラスを分けちゃう。「サークルのユーザーを取る」というメソッドをもつクラスにする

ドメインサービスがビジネスロジックを書く場所か?

いろんなエンティティなどを強調させるのであれば、それはアプリケーションサービス。 ドメインサービスはエンティティ・バリューオブジェクトでは不自然なものをロジックにする

検索など複雑なSQLが必要な場合

CQRSの概念を活用する。アプリケーションサービスの直下に複雑なSQLを書いてしまう。Queryはフロントの都合などが多い。その場合はREADMODELとしてのアプリケーションサービス。

まとめ

理解が曖昧な状態で軽量DDD実践していたので、理解が深まり今のコードを改めて見直そうと思います。

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を理解する

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としての訂正をもってツールなどを作成・公開していく。

まとめてみて

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

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