OpenAPI定義に沿ってバリデーションをしてくれるGoのライブラリを書いた

GitHub - aereal/go-openapi3-validation-middleware: net/http middleware to validate HTTP requests/responses against OpenAPI 3 schema using kin-openapi.

kin-openapiというOpenAPI 3定義を読んでリクエスト・レスポンスのバリデーションをしてくれるGoのライブラリがあるんだけど微妙に使い勝手が悪い。 素朴に使おうとするとHTTPハンドラ内でバリデーションに関するコードを書く必要があって関心を分離させるという目的を果たすにはちょっと弱いし、得られたエラーを一貫して取り扱うにはエラーをHTTPレスポンスに加工して返すところまで一気通貫で取り扱いたい。

Goでnet/httpを使ってHTTPサーバを書く時は、RackやPlackのように、ミドルウェアあるいはサンク (thunk) を組み合わせてリクエスト/レスポンスの参照や加工を行えるので、この仕組みに乗りたい。

というわけでREADMEのsynopsisから引用:

import (
    "net/http"

    "github.com/aereal/go-openapi3-validation-middleware"
    "github.com/getkin/kin-openapi/routers"
)

func main() {
    var router routers.Router // must be built with certain way
    mw := openapi3middleware.WithValidation(openapi3middleware.MiddlewareOptions{Router: router})
    http.Handle("/", mw(http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
        // this handler is called if validation succeeds
    })))
}

見てわかるように、http.Handlerを扱えるライブラリならnet/http以外でも使える。 実際に自分はhttptreemuxで使った。

WithValidation はリクエストとレスポンスどちらも検証する。 用途に合わせてリクエストのみを検証する WithRequestValidation, レスポンスのみを検証する WithResponseValidation というエントリポイントをそれぞれ用意してある。

  • 自動テストやQAが十分であればレスポンスの検証は本番環境では不要という考え方もありうること
  • 実装の都合上、書き出されたレスポンスボディをすべてメモリ上に確保するためGoのio.Writerインターフェースの良さをスポイルしてしまっていること

……といった理由からレスポンスは検証せずリクエストのみ検証するというオプションを用意した。 ちなみに WithValidationWithRequestValidationWithResponseValidation を合成しただけ。ちょっとおしゃれで好き。

実装してのおもしろポイントといえばhttp.ResponseWriterを独自実装したところとか。

go-openapi3-validation-middleware/response_writer.go at main · aereal/go-openapi3-validation-middleware · GitHub

http.ResponseWriterはインターフェースなのでnet/httpがデフォルトで持っている実装以外を使うこともできる。

このライブラリではレスポンスボディとステータスコードを保持するための実装を書いた。 レスポンスを検証する際の最終的なレスポンスは、内側のHTTPハンドラが書き出すかもしれないし、このライブラリがエラー報告を書き出すかもしれない。 なのでbufferingResponseWriterのWrite()とWriteHeader()の書き込みインターフェースはそれらを呼び出した時点では引数を保持するだけにしてある。

レスポンスを書き換えるパターンのミドルウェアは初めて書いたので手札が増えてよかった。

as a builder

ソフトウェアエンジニアリングやると究極的には一行もコードを書かなければバグが混入することもないしなっていう気持ちになることがある。

それはテコを効かせるエンジニアリングの考え方として理に適っているので納得している。

早すぎた最適化とかは「やりすぎ」自体が問題なのではなく最適化という枝狩りの山はよく外れるからエビデンスを集めてからやれということだと思うし、最初から将来に渡ったユースケースもカバーしてめちゃくちゃ速いものを作れるならそれに越したことはないはず。

一方でソフトウェアコンストラクションという手段にこだわりたい自分もいて、この時折顔を見せる自分はなんだろう、とずっとモヤモヤしていた。

ふとこれはビルダーとしての自分だなと気がついた。作ることが手段であり目的でもある存在としてビルダーというラベルはしっくりくる。

常に便利なソフトウェアを作ってものごとを良くしていくというやりかたにこだわろうとする自分をビルダーという振る舞いにあてはめて認めてあげたい。

言葉を尽くす

大抵の誉め言葉を嬉しいとは感じない。どれもこれも社交辞令に聞こえる。なぜ社交辞令に聞こえるかといえば、着眼点がずれていたり、解像度が低かったりするから。

これも本当にズレている・見えていないだけのこともあれば、当人の認識は的を外していないけれどもそれが言語化する際にスキルが伴わず伝わらないだけということもあろう。

 

ポジティブ・ネガティブ問わずフィードバックする際に限らず、たとえばタスクひとつ振る際にも背景や要件だけではなく「なぜあなたを指名したか」「これを通してあなたが何を得ると期待しているか」といったことを過不足なく伝えることはこだわり徹底したいことのひとつ。

別に指名の理由が大仰なものと限らず「単に暇そうだったから」ということもあるだろうし、それはそれで良いと思う。その場合は正直にそう伝える *1。でも「他に頼れる人がいないのでお願いしたいと思っている」とそう伝えることはできよう。

 

大人数の群として大きな仕事をやっていこうという中でどうしたって個人の自尊心は後回しにされがちなのは否めない。

もちろんそれは当人の内的なものであって外から与えたり充たすような類のものではない。

ただ、不足や欠落があって少しずつ瑕がつき、いずれ大きなものとなるというのはよくあること。

何より自分にとっては言葉を尽くして伝えようとしてくれる行為そのものに好感を抱くし、群を動かし大きなことを成そうとする能力があると信頼に足る。

 

1on1を、会議よりも有意義な対話にするためには、もっと自然体で臨む必要があります。メンバーの言葉を聴き、感じた印象はストレートに伝えます。とりわけ、お互いの感情を織り交ぜながら対話するほうが伝わりやすくなります。

リーダーとメンバーがお互いの感情を伝え合い、感情面での共感や反発があって「ガチ対話」が生まれやすくなります。テクニックを身に付けていくことはもちろん重要ですが、テクニックを活かす土台作りとして、感情を共有しあうことを意識しています。

「ガチ対話」でエンジニアチームのエンゲージメントを高める1on1の工夫 - ZOZO Technologies TECH BLOG

最近インターネットで見かけた似た考えについて書かれている記事。

 

自分にとってはグレード昇格時の id:motemen さんからのコメント・フィードバックがとても嬉しくて印象に残っているので、目指すべき姿のひとつとなっている。

*1:さすがに「暇そうだったから」とそのままは言わないけれど

入社以来未だオフィスに踏み入れていない自分の転職とオンボーディングについて

前回までのあらすじ

転職した: 新しい職場で半年経った

面接を受ける1年前 (2019年初頭) にカジュアル面談に行った時にオフィスを訪れて以来、面接から入社後に至るまで自分は一度も現職のオフィスに踏み入れていない。
転職から入社

転職活動

新しい職場を決めるにあたって重視した点は金沢からの勤務実現に前向きか同僚となるメンバーが刺激的かどうかの2つ。

これは以下に引くようにこれまでに言及してきた:

数年前に観光で訪れた金沢を歩いてから一目惚れしてしまい、自分がここで生活する想像をするうちに単なる夢想から具体的に実現することを考えはじめた。
これを書いている時点で、株式会社はてなの事業拠点は東京と京都のみであり、在宅勤務は育児や介護、その他会社が認めるに足る理由があるケースのみ認められている。
平時は週数日程度スポットでの在宅勤務はマネージャーと合意した上では認められている。またコロナ禍においては在宅勤務推奨となっている。ただし、継続的にフルリモート勤務というのは上記の通り認められる事例は限定的になっている。
このまま在職しつづけても実現が難しそうと判断したのが、転職を決意した最大の動機といえる。

株式会社はてなを退職

転職先を決めるにあたって一緒に働くメンバーから刺激をもらえそうかを一番重視した。
これは抜きん出たタレントを持っているとか輝かしい経歴を持っているかとかではなく:

  • 知的好奇心を持っているか
  • それがよく表出しているか (= アウトプットされているか)

……ということを重視している。

新しい職場で半年経った

転職ドラフト

上述の条件の他、漠然とWeb系で、くらいしか思い付かなかったのでとりあえず世にどんな企業があるのか知ろうと思い転職ドラフトに登録した。
当初は自分にスカウトが来るとしてどれくらいの条件なのか知りたい、くらいの気持ちだったけれど。

転職ドラフトに登録していくつかスカウトをもらってわかったことがいくつかある。

まず、提示される条件は自分の市場価値がどうとかより企業が儲かるかどうかが支配的ということ。
具体的には、スカウト文言の熱量の高さと年俸の高さに相関はあまりなかった (熱烈だけど低いというケースはままあった) し、額面は高いけれど明らかにこちらのレジュメ読んでいないなってわかるケースもあった。
考えてみれば当然ではある。
「リモートワーク希望、で少なくとも首都圏では働きたくないです」ってレジュメに書いてあるのに「当社の(都内の)オフィスにはこんなに福利厚生があって〜」みたいなことをスカウト文言に書いていた企業は申し訳ないけど笑ってしまった。

金沢から勤務したいっていう条件が折り合い付かなかったのでお断りさせていただいたけれども、PLAIDからのスカウトはこちらのレジュメに書いてあることをしっかり読んでもらえたことがわかって嬉しかったし好印象だった。(レジュメに載せた過去の発表内容や就労条件についてちゃんと言及いただいていた)
今回はマッチしなかったけれども記憶には残ったので、こういう細かい取り組みが強みになるんだろうなーと感じる。

企業探し

そんなわけで転職ドラフトに参加してみて、漠然と首都圏や近畿で働いても良いなら便利な仕組みではありそうだが自分の条件ではファジーすぎるので不適と判断して地道に自分で探すことにした。

まずremote-in-japanを眺めてみることにした:
GitHub - remote-jp/remote-in-japan: Tech companies in Japan that hire remote workers

よくまとまっていて便利。転職活動をはじめた2020年前半はCOVID-19の影響下にあり半ば緊急避難的にリモートワークをやっている会社も多かったけれども、やはり以前から運用している組織のほうがいろいろと不都合はなかろうと参考にした。

が、結論からいうとここからはマッチしなかった。事業会社かどうか・メンバーの魅力 (そもそも誰が所属しているかよくわからないとかあった) などを考えるとリモートワーク可以外の点で決め手に欠けた。

面接

けっきょく知人の所属している・していた数社にカジュアル面談を設定していただき、さらにそこから合いそうだと感じたいくつかの面接を受け、最終的に現職の内定をいただき受諾となった。
面接はすべてzoomなどを利用した。

入社後

全社的に半強制的なリモートワークにあった (ある) ので、オフィス勤務時のように黙って座っているだけで新顔だなって覚えてもらう機会はなく、能動的に行動しないとかなり仕事しづらいだろうと考えていたのでとにかく存在感を出して認知してもらうことを考えた。

特に自分は基盤バックエンドというサーバサイドのお困りごと全般をなんとかするというプロダクト横断のチームに配属されたので、考えなしでいると薄く広くという関係構築になることが予想されたのでかなり気にかけた。

Slackで存在感を出す

リモートワーク環境においてはチャットで見かけるかどうかが良くも悪くも存在感に繋がると前職から感じていたので、まずSlackでの認知を高めることにした。

xxx-zassouのようなカテゴリごとの雑談チャンネルがいくつかあるので、とりあえずそこで絵文字のreactionをつけるくらいから始める。
reactionをつけること自体が認知に繋がるとは思えないけれど、とりあえず自分がそのチャンネルの雰囲気に馴染むことを目的として絵文字をつけていった。

慣れてきたら発言したり。分報チャンネルで仕事するのはやめよう高校出身なので、用意されていた *1 分報チャンネルのtopicは「社内Twitterです」と書いて未だに仕事の話はほとんど書いていない。archiveしても良い気はしているけれど、思いがけないコミュニケーションが生じていてこれはこれで惜しいのでそのままにしている。

しかし振り返ってみても「あとはがんばる」以上の取り組みをしていないな。

顔出し

zoomやGoogle MeetなどでのWeb会議ではカメラの映像を映すようにしている。
少しでも情報量が増えたほうが相手に認知してもらうフックは増えるので出したらいいかと思ってそうしている。

実際「そのフリースHaglofsですか?」とかフックが生まれたりしているのでわりと良い取り組みなのだと思っている。

まあこれは自分が必要性を感じているから苦に感じないのであって、結果が同じでも会社に「出しましょう」って言われたらエッとなりそうだなとは思う。
ので、こういう良い変化はありましたよとは書くけれど無理に勧めることはしない。

文化のすりあわせ

よく中途で入った人は「新しい風をもたらすことを期待しています」と言われるし、実際言われたけれど、しかし新しい風がなにもかも良いかというとそうではない。
なにより「前職ではこうやったで」おじさんは、たとえ言っていることが正論であっても量が過剰だったり、現職へのリスペクトがないと鬱陶しがられるだろう。

もたらす情報:受け取る情報 = 3:2くらいの割合を心がけた。根拠は特にない。求められていることに違いはないだろうから、
あと単にまだ知らなくて知っておいたほうが良いこととの比ってこんなものかな? という印象。

いかがでしたか?

開発者ブログの再興とか調整事も必要なプロジェクトを提案して軌道に乗せられていたりと、本来のパフォーマンスを発揮するには3ヶ月くらいはかかるという定説から外れてわりと良い仕事ができているのでうまいことやれていると評価して良いでしょう。

もちろん現職が提供してくれたオンボーディング施策によるところも多分にあるだろうから、ここに書いたことが結果のすべてだとは思わないけれども。

初めての転職がフルリモート下というわりとハードな状況のわりにはよくやっていると思うので自信にはなった。

*1:事前に作られていた

DDD is overratedについて

DDD is Overrated | Stefan Tilkovについて。

DDD is overratedの自分なりの受け取り方

  • DDDだけが設計手法や考えではないんやで
  • 必要なら(DDDにおけるaggregateやvalue objectのような)概念に対する名前を自分たちで付けてもええんやで

自分の考え

筆者が言わんとする「盲目的にDDDを受け入れたり、その他の手法などの探索を諦めるような思考停止はいかがなものか」ということは理解はできる一方で、生半可な労力でもってこうした一般的な設計手法の(再)発明を試みるのは概ね良い結果をもたらすとは言えないのでやめたほうが良いと思っている。

DDDなりPoEAAで紹介されているパターンなりは、数多くのプロジェクトを調査して頭の良い人が心血を注いで一般化したもので、完璧でないにせよ少なくとも見てきた事例の多さという点は評価できそう。

一方、事業(サービス)を持ってその開発をしている組織のデベロッパーが立ち会うプロジェクトの数は知れている。 それはたとえばLINEやYahooのような規模であっても一般化を踏まえるとサンプル数や偏りの是正は不足していると考える。

そも事業ドメインの知識モデリングだけでもかなりタフな仕事なので、ましてやその一般化をしようとするのはコスパが悪い。

餅は餅屋ではないけれど、こういった開発手法や設計・分析については借用に留め、発明を試みないほうが総合的な生産性は高く保てる。これらは最終的に良いソフトウェアを作るためにあるので。

もちろん選ぶのがDDDでなくとも良いし、きちんと批判的に見て合いそうか評価することは大事だけれども、ある程度は型にはまる・型通りにやるということも大事だと考える。

新しい職場で半年経った

from: 株式会社はてな 退職エントリ
to: 株式会社Classi 社の開発者ブログに書いたエントリ

決め手

転職先を決めるにあたって一緒に働くメンバーから刺激をもらえそうかを一番重視した。
これは抜きん出たタレントを持っているとか輝かしい経歴を持っているかとかではなく:

  • 知的好奇心を持っているか
  • それがよく表出しているか (= アウトプットされているか)

……ということを重視している。

転職ドラフトに参加したり、いろいろな企業を見る中でbuildersconなどのカンファレンスで顔を合わせて話すことがあったid:nkgt_chkonkさんやid:lacolacoさんが所属していることを思い出した。

所属がはっきりしているメンバーで事前に認知していたこの2人がいたので、先に述べたような資質を引き出す働きかけは頑張れそうかなと思えたのが決め手になった。

いろいろ考えたけれど初めての転職だし、うまくいかなかったとしてもこの2人と働いた経験が短くとも得られたら元は取れるかなと思えた、という防衛的な見方もある。

やっていること・やりたいこと

基盤バックエンドチームというサーバサイドのソフトウェア技術的な困り事全般をなんとかするチームにいる。
……はずなのだけれど、もはや「サーバサイド」「ソフトウェア技術的」という但し書きすら怪しくなるくらい様々なことに手が出せているのでざっくりソルジャー上がりのなんでも屋って思っている。

この基盤チームやプロダクトチームなどの現在の組織に関する情報の一端はセキュリティインシデントと大規模障害を経てClassiは開発組織をどう変化させたのか - Classi開発者ブログに書いてもらえた。

チーム・機能横断の基盤システムの設計と開発

dron: クラウドネイティブなcron代替の紹介 - Classi開発者ブログ

(自分にとっての) 本業というかんじ。得意かつ求められているかつ好きなこと。

今のところうまくいっているけれどドメイン知識がまだまだ足りていないなーと感じている。ので後述するようにプロダクトチームに出向しはじめた。

開発者ブログの編集長業

決め手でも述べたように好奇心とその表出が強い人間が好きで、そういう人間が集まっていると自然とブログを書いたりといった活動が生まれると信じている。
Classiは2020年4月に高負荷インシデントが起きたりなどの事情があってアウトプットがすっかり止まってしまっており寂しかった。

一方で社内のesaには日々のサービス開発・運用で発見したことが想像以上に活発に投稿されていて、アウトプット自体はあったのは嬉しい誤算だった。
単に対外的に出していないだけでアウトプットに対する感度は決して低くなかった。

とはいってもこのままだと進展しないのも確かなので「復興させたいです」と手をあげていろいろやらせてもらった。

  • 編集部の立ち上げ
  • 公開スケジュールの段取り
  • ブロガーのスカウト

……など。

編集部は自分とVPoEでミニマルに立ち上げて今は3人体制。まず開発者ブログをどう位置付けるのかということを表明し、興味を持っている人やステークホルダーに判断しやすい環境を整えた。
向こう1〜2年のあいだは執筆者が不特定多数の社外の読者に自分たちの取り組みを過不足なく理解してもらうだけのアウトプットをするスキルを養うことを目的としその場として開発者ブログを整えるということにした。
採用や広報のツールとして活用するという視点は、少なくとも現時点では時期尚早かつ高度すぎるのでうまくいかないだろうと思ったのでスコープから外すようステートメントに盛り込んだ。なのでPVやSNSでの反響は主要なKPIとして見ないことにしている。

プロダクトチームに出向しての草の根活動

テックリードの相談相手になったり外様として「この会議の位置付けってどういうかんじでしたっけ」みたいなことを言ったり改善の意見を出したり、もちろん一緒にちょっとしたタスクをやったりといった本当に様々なことをやっている。

これは自分がプロダクト領域の知識を付けるという意味もあるし、いろんな環境・状況での開発経験がちょっとある人間としてチームに新しい視点をもたらすという意味もある。

11月くらいから始まって評価は上々っぽいけれど塩梅がむずかしいな〜と日々悩んでいる。自分がしゃしゃり出て改善できたとしても、きっとそれはチームの糧にならないだろうし、そもそもチームの状況・事情を咀嚼しなければ「正しいだけの正論」になるだろうし。
かといってチームに悪い意味で馴染みすぎたら役割を果たせないし、というかんじでとても難しい!
が、少なくとも自分はプロダクトの知識や事情のキャッチアップが進んでいるので成果は大きいと感じる。

自分の働きが効果を発揮できているかは、おそらく自分が出向をやめたあとでしか評価できないので今はあれこれ模索中。

事前の印象と変わらないところ・異なったところ

相対的に見て前職と比べて所属を明らかにしてオープンな活動をしている人は少なかったので印象らしい印象はそんなに強いものはなかったけれど、面接などを通して文化的背景がさほど遠くないと感じ、それは今も変わらない。なんというか落ち着きがあると思う。

印象的なのは社内外で開発組織のマネージャーやリーダー経験のある人が多いので、自分のようにマネジメント・メンタリングが得意じゃない人間でもそういう仕事をやっていてささいなアドバイスをもらえて孤独感を感じにくいし、リーダー・マネージャーポジション以外にそういう背景・キャリアの人がいるのは層が厚くて良いところ。

ギャップを感じているというほどではないけれど、プロダクトチーム制への変化はけっこうドラスティックで無理が生じているところも見え隠れしている。
まあこういうのはビッグイベントの当事者でなかった自分のようにMPを消耗させた経験のない人間がサポートしていくのが良いんだろうなと思うので、しばらくそこらへんを頑張りたい。

Google Formでお手軽に自分のヘルスチェックをしてみる

気分によってパフォーマンスが左右されるな〜と数年前くらいから自覚するようになり、自分の生産性とどういう相関があるのか・ないのかを知りたいと考えた。

生産性は普段の仕事のアウトプットで評価すれば良いだろうから、あとは気分を記録すれば良いだろう、ということで掲題の通りGoogle Formで手軽に始めていたことを思い出したので書いておく。

収集

f:id:aereal:20210106173225p:plain

Google Formで記録

こういう素朴なGoogle Formを作った。

  • 😀 良い
  • 😎 最高
  • 😑 感情なし
  • 😱 大変だった
  • 😇 大いなる動きの前では何もできないちっぽけな私

みたいなかんじ。

f:id:aereal:20210106173138p:plain

Slackで毎日リマインド

これをSlackで毎日リマインドする。数年前に素朴に作ったけれど、今だとSlack AppにしたらSlack上で完結して良いかもしれない。

収集と可視化

Google Spreadsheetsに送られるのでいろいろグラフを出してみた。

まず曜日によって傾向が変わるのかを出してみる。

f:id:aereal:20180404094950p:plain

曜日ごとのバブルチャート

縦軸が曜日で、1が日曜日、7が土曜日。

どうやら自分は尻上がりタイプらしいということがわかった。

 

またこの画像を保存した当時は水曜日と金曜日に厳しい気分になることが多いようだった。

確か厳しい定例ミーティングがあったのだったような。

f:id:aereal:20180404094955p:plain

期間での感情の割合

 期間全体だとこういうかんじ。こうしてみるとわりとまんべんなく現れており、感情の浮き沈みがはっきりしているといえそう。

 

カレンダーの予定と組み合わせての評価とかやったらおもしろそうだと今思った。

データの集計方法はあまりに素朴すぎるので改善の余地はある気がする。

2020の振り返り

去年

作ったもの

仕事

はてな

退職

株式会社はてなを退職 - Sexually Knowing

8月を最終出社日として退職した。来年から金沢に引っ越す。

退職する時に同僚からフィードバックをもらう - Sexually Knowing

今でもたまにもらったフィードバックを読み返すことがあるのでやってよかった。

新メンバーのメンター

4月に新しく入ったメンバーのメンターをやった。

メンター自体は何度も経験があるけれど、その時に辞意は固めていたこともあり自分の考えとか振る舞いとかを伝えるっていうことを意識してみようと思い、いろいろメンタリングのやりかたを変えてみた。

かなりまめに様子を見たり、正解のないものごとについて「自分はこういう風に考えている」ということを伝えることが多かった。 これまで価値観のインストールはメンタリングの範疇を越えていると考えて意図的にやってこなかったけれど、新メンバーが新卒ということもあり価値基準が確固たるものになっていない内から「あとはあなたの考えに基づいて行動してね」では突き放しすぎかなとも思いやってみることにした。

もちろん染まりきっていない新卒だからこそ、自分の一挙一動に染まりやすいので果たしていかがなものかという思いはあったけれども。

その他

AWS API Gateway HTTP APIを使って認証エンドポイントを生やしたりといった仕事をしていた。

チームメイトをつかまえてLambdaとかの知識を伝授したり、単に作る以上のことはできたと思う。

現職

AWSでちょっとしたシステムを作ったり、他のチームに出向いてDX改善おじさん業などをしている。

来年

最高のアーキテクトになる - Sexually Knowing

これかなあ。転職したので、新しい職場でちゃんと実績と信頼を勝ち取っていきたい。

ポジションを作る動きが1年後にできていたら良いかなあ。

あとは新天地で楽しく生活したい。

たいへんな仕事は仲間を募ると良い

重い仕事・比較的やりたくない仕事・とっかかりが見つからない仕事など、アサインされたけれどどうにもやる気が出ない仕事に出くわすことはしょっちゅうあると思う。

そういう時におすすめしたいのが「誰か一緒にやりませんか」とペアプロ・ペア作業相手を募集すること。

実際に一緒に作業することになれば:

  • 相手の作業時間を確保するので否応なしに向き合うことになる
  • 視野が広がる
    • 単純に他人の目が増える
    • またプレッシャーが減ることで自身の視野も良くなりうる
  • 作業効率が上がる
    • 単純作業がたくさんある場合なんかにはとても助かる

また、チームの状況がそれを許さない場合でも:

  • なんか大変そうだなというアラートが届く
    • だいたいアラートを上げるのが苦手な人は顔色を変えないことが多いので、周りからフォローしにくい
  • アラートをあげる心理的障壁が低い
    • 「つらいのでやりたくないです」と言える人はなかなかいないと思うし、言ったとして何かを失うリスクも高い
    • 「つらいので誰かと一緒にやりたいです」だとやりかたを変える提案なので言う側も受け取る側もそれなりにポジティブに捉えられる

というような話をチームメイトにした。

この考えは自分が独自に辿り着いたわけではなくて id:hitode909 さんが言っていたので影響された。 一緒に仕事していた時にペアプロ・ペア作業の効能について話した時だったと思う。

ブログに書いていなかったかな〜とあれこれ調べたけれど見つからないので書きました。 かわりに見つけたお気に入りツイートを置いておきます (そのエピソードの登場人物が「hakobeさん」だったはずなのでそれで検索した):

Twitterでつぶやいていたらhitodeさんが発掘してくれました:

blog.sushi.money

こちらも併せてご覧ください。また引き続きリリカルなのは大学のエピソードもお楽しみください。

Re: ネットワーク越しリトライ考

moznion.hatenadiary.com

  • サーバが脆弱という意味では弱者だけれども、一方でreadinessとかの豊かな情報が欠けているという意味ではクライアントもか弱い存在で、このミスマッチが根本的に問題を難しくしていると思う
    • 素朴なモデルだとクライアントは自身で完結して得られる情報からのみリクエストを制御しなければいけないけれど、サーバが許容できるかは個々のクライアントだけでは判断できないというのも難しい
    • クライアントにリトライを任せるというのもけっこう難しい話だと思っていて、クライアントはサーバに言わば計算機資源の外注をしたいことが多いはずで、リトライを重ねるとクライアントの資源も消費されていくっていうのも難しい
  • 利用者が、Web APIで言うSSKDsLSUDsなのかにもよりそうだけれど、メッセージを介してやりとりするアクターモデルにするっていうのが最もサーバが防御的に振る舞えると思う
    • メッセージブローカーにいわゆるサーキットブレイカー的な役割を負わせるかんじ
    • あるいはUDP的な、サーバが応答をしなくても良い = メッセージの到達不可能性を折り込んで、クライアントが常に悲観的に振る舞うっていうモデルもありそう。サーバではstrong consistencyは狙わない

ひどい目に遭いそうなところからテストを書く

blog.sushi.money

僕も最近は正常系から書くことが多いです。こうすると悪い設計に早く気付きやすいという利点があると感じています。 ここでは単体テストのような開発者向けのテストを想定していて、E2Eテストのようなテストでは必ずしも当てはまらないでしょう。

最初にテストを書く時には何も準備がない状態から始まりますが、その時にとても素朴な異常系から始まると整える事前条件が少なく済んで簡単に書けた、という体験になると思います。

そこからインクリメンタルに事前条件を積み重ねて、複雑なメソッドの動作を確かめていきますが、その場合の開発体験はコピペしつつちょっとずつ整えていくという風になり、都度の負担はそれほど高くならないでしょう。

一方、最初に正常系から書く場合、あらゆる事前条件を把握し、それを整えるコードを書く必要があります。

理想的に実装されたメソッドは、どちらの進め方であっても体験は大きく変わらないでしょう。 でも最初からうまくいくことは稀だしインクリメンタルに良くしていくためのハーネスとしてテストがあるので、ひどい時のことを考えます。 たとえば現在時刻に基づく計算をしているとか、ファイルシステムや外部のAPIに依存していてモックが必要だったりとか。

僕の感覚としては、素朴なケースから始めて徐々に重ねていくボトムアップのやりかたでテストを書いていくと、こういったテスタビリティの低い実装に対する感度が鈍るのではないかという仮説を持っています。

テストを書いていって大変だった度が同じ100のメソッドのテストを書くことを考えて、最初にあらゆる事前条件を把握して書く場合は100の大変だった度を感じることになる一方、ボトムアップだと10の大変だった度が10回繰り返されますが、総合的な大変だった度は異なるのではないか、ということです。

なので、最初にひどい目に遭う蓋然性の高いところから書くことで、これはまずい! という感覚を鋭敏に向けられるのでよりよい実装を得やすいのではないか、という意見です。

AWS CDKやGo関連で最近作ったものたち

cdk-dynamodb-expression

aereal/cdk-dynamodb-expression: DynamoDB expression builder for AWS CDK

AWS CDKでDynamoDBの式を書く時に便利なグッズ。

usageより:

import { DynamoAttributeValue } from "@aws-cdk/aws-stepfunctions-tasks";

    const builder = new ExpressionBuilder();
    builder.update`SET Executing = ${DynamoAttributeValue.fromBoolean(true)}`;
    const {
      updateExpression,
      conditionExpression,
      expressionAttributeValues,
      expressionAttributeNames,
    } = builder.aggregate();
    expect(conditionExpression).toBeUndefined();
    expect(updateExpression).toBe("SET Executing = :v0");
    expect(expressionAttributeNames).toBeUndefined();
    expect(expressionAttributeValues).toStrictEqual({
      ":v0": DynamoAttributeValue.fromBoolean(true),
    });

DynamoDBの式に属性の値をリテラルとして書くことはできず、プレースホルダを書き、プレースホルダと実際の値の辞書をそれぞれ与えるようになっている。

式に現れるプレースホルダは当然ユニークでなくてはならないけれど、シンボルテーブルの管理を自前でやるのもめんどうなのでtagged template literalを使うことで、式にそのまま値を埋め込んでいるような書き味なのがオシャレだと思う。

また、色気を出してプレースホルダの生成に使うカウンタをgeneratorで実装した。

go-dynamodb-attribute-conversions

aereal/go-dynamodb-attribute-conversions

AWS SDK for GoAWS Lambda for Goの間でDynamoDB関連の型に互換性がないので変換するライブラリを書いた。

AWS SDK for Goにはdynamodbattributeという便利パッケージがあることに最近気がついて、たとえば UnmarshalMapmap[string]*dynamodb.AttributeValue をstructにUnmarshalしてくれる。 DynamoDBのO/Rマッパを意識したライブラリは世にいくつかあるけれど、個人的な用途ではこれとdynamodb/expressionというDynamoDBの式を組み立てる便利パッケージがあれば十分だと感じた。

ところでAWS Lambda for GoはLambdaのハンドラを書く時に便利な型も提供している。 eventsパッケージ以下にあるのがそれで、CodeBuildやKinesisから呼び出されるペイロードの型が定義されているので、それらを購読するLambdaハンドラを書く時はこの定義を使うと便利。

その中にもちろんDynamoDB Streamsを購読する時の型も定義されているけれど、これと前述のAWS SDK for Goの型に互換性がない。 なので、Streamsを購読して何かするLambdaハンドラを書く時に、ペイロードにやってきたアイテムを構造体にUnmarshalする時にAWS SDK for Goの型に直さないといけない。

一対一対応しているので実装は大変ではないがちまちましているし、けっこうありがちなパターンっぽく、かつAWS Lambda for Goの型をSDKに寄せるP-Rは2年以上動きがなく、コメントのやりとりを見てもwon't fix感が漂っているので書いた。

go-httpretryafter

aereal/go-httpretryafter: Provides functions to parse Retry-After header.

Retry-Afterヘッダをパースして再試行して良い time.Time を返す関数を提供するライブラリ。

GoでHTTPリクエストを良いかんじに再送するライブラリはいくつかあるけれど、どれも一長一短で用途に合わなかったのでリトライ処理は自前で書くことにした。

そのためにRetry-Afterの仕様を調べたところ、実は絶対時刻と相対時刻の両方が指定できるので、これはアプリケーションの中で実装するにはちょっとめんどうだなと思い外に出した。

aws-cdk-apigw-documentation

aereal/aws-cdk-apigw-documentation: Collection of constructs for API Gateway Documentation parts.

AWS API Gateway v1のREST APIにはDocumentation PartというOpenAPIに準拠した追加のドキュメンテーション情報を与えることができるのだけれど、これのAWS CDK Constructsがないので書いた。

Documentation Partについてはちょっと前のメモもどうぞ: AWS API Gatewayのdocumentation partに関するメモ - Sexually Knowing

関係ないけれど命名規則がけっこうぶれている。aws-cdk-なのかcdk-なのか。

やたらと短いエイリアスは使わない

Gitもシェル (zsh) もよく使うコマンドをエイリアスとして設定して任意の入力で呼び出すことができる。

このエイリアスについていくつか派閥があると感じていて、おおまかには:

  • エイリアスをまったく使わない
  • 入力の手間を減らすため極限まで短いエイリアスを使う
  • よく使うコマンド・オプションの組み合わせに説明的な名前をつける

……という派閥に分類できると思う。

自分は3つめの「よく使うコマンド・オプションの組み合わせに説明的な名前をつける」に属する。

短いエイリアスへの苦手意識

衝突しないようエイリアスを管理するのがだるい

エイリアス名前空間を通常のコマンドと共有しているので、それらと衝突しないよう管理しなければいけない。

短い名前を設定しても思い出せない

よく使うコマンドなら手癖で打てるだろうけれど、ごくたまにしか使わないコマンドのごく短いエイリアスを思い出せる気がしない。

これはエイリアスではない通常のコマンドでも起きるけれど、コマンドは検索なりすれば出てきて辿れるのでリーチできるが、エイリアスの場合は検索しても出てこないので死にエイリアスになったままになりがちという問題があると思う。

これはシェルやGitの設定でコメントを書くとか

誤爆のリスクが高まる

たとえば grgit reset --hard HEADエイリアスしているとして、 grep と打とうしたが誤って gr でエンターを押してしまって誤爆すると悲惨なことになる。

危険な操作にエイリアスをつけるなとか、いろいろ突っ込みどころはあるが、操作者に責任と自由が委ねられているシェルにおいてわざわざ危険な操作を実行する敷居を下げることもないなと感じている。

検索性が低い

シェルのヒストリ検索は文字列の部分一致で行うのが常なので、ごく短い文字列にしていると発見しづらい。

これは技術的に挽回する余地はあると思うけれども、後述するように長いが説明的な名前をつけて、それを検索しやすくするというほうが技術のテコをきかせやすく総合的に生産性が高まると感じている。

説明的な名前をつける

特にGitの操作はやたらと難しいので自分でいろいろエイリアスを作っている。たとえば:

  • git cp: git cherry-pick
    • ファイル操作のメタファーになぞらえて
  • git interactive-rebase, git continue-rebase, git abort-rebase: それぞれ git rebase --interactive, git rebase --continue, git rebase --abort
    • git-rebaseはinteractiveとそれ以外でかなり性質の異なるサブコマンドだが1つに押し込められておりかなりヤバい設計になっている
    • 区別しやすくなるだけではなく、先頭一致で検索する際にサブコマンドの先頭を分けることで誤ったrebaseのオプションを選ぶことを防ぐ意味がある
      • git rebase まででC-pすると git rebase --continuegit rebase --abort も候補に含まれるが、 git cont を入力してC-pすると git abort-rebase が候補に出てこない

など。

そもそもGUIを使えばっていうのはごもっともだと思うけれど、なんだかんだ複雑であまり整然としていないと批判されることの多いGitのCLIも覚えておけばリポジトリの統合とか凝った操作をする時に役立つことがあるので、そこは妥協している。

組織をプロダクトと捉えてみる

  • ※組織の話は詳しくないので自信はないけれど、こう思ったという話を書きます
  • ※現在の所属組織の社内ブログに書いた内容を一部修正して転載しています

プラットフォームのプロダクトマネジメント

メルカリのSREであるdeeeetさん (eは4つ) のこの記事が良かった: 社内PlatformチームのProduct Management | SOTA

直接エンドユーザーに面しないプラットフォームであってもプロダクトマネジメントの基本的な考えや方法論を適用し「ちゃんと」やっていく話と、エンドユーザー向けのプロダクトマネジメントと異なるビジネスとのバランスの話が挙げられている。 参考となる書籍やページがたくさん挙げられているので、おすすめ。

特にどのような優先度がやるかについて紹介されていた方法が自分にとっては初見で有益だったので紹介:

大きなタスクの分類としては左から「User asks」「Platform quality」「Long term key initiatives 」が挙げられる.それぞれの意味は以下.

  • User asks: 開発者の問題を解決するタスク
  • Platform quality: Securityや技術的負債などPlatformの質を担保するタスク
  • Long term key initiative: 長期的な投資のためのタスク

Will Larsonはこれらを40:30:30でバランスをとるのが良いとしている.自分たちは完全にこの比率に沿っているわけではないが分類を含めて参考にしている.

40:30:30の根拠は原文を読んでいないのでよくわかっていない。あとで読む。

他の指標としてBusiness, ROI, SLOが挙げられている。これはまあ普通なかんじ。

組織をプロダクトとして捉えてみる

Developer Experienceがバズワードしていった流れは、作るものが複雑になってきて成果の精度や価値を左右する要素として過程の改善が占める割合が小さくない・投資効率がそれなりに高いと認知されてきたからだと思う。

古くはアジャイル開発を始めとして、最近ではソフトウェアエンジニアリングと組織開発の両方に立脚して意義や効果を説いたという点では広木さんの『エンジニアリング組織論への招待』も挙げられる: エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

これらの背景から組織をプロダクトとして捉えると、改善の進め方やうまい機能のさせかたは実は身近なところから応用できるのかもしれないと考えた。

たとえばプロダクトを開発する部署の顧客は誰だろうと考えると:

  • 経営者:競争力のあるプロダクトを速く正しく作る実行力を提供する
    • 主要な結果の例: 設定した稼動率目標の達成、競争力の獲得
  • プロダクトを開発する部署の各メンバー: 知的好奇心を満たすに足る場や業界で生き残る知識・スキル獲得の機会を提供する
    • 主要な結果の例: 昇給

……など。

同様にプロダクト開発の考え方を適用すると、自分の所属の開発部署をどう変えていくかというロードマップを敷くのは未だできていないことで効果が見込めることかもしれない。

Roadmapを作る意義は大きく2つある.まず開発チームからするとどのような機能がいつ頃利用可能になるのかが明確になる.(略) 次にPlatformチームのメンバーからすると今後何を作るかが分かるため,実装時の意思決定の助けになる.「3カ月後にこういうことをやります」と分かって書くコードと、知らないで書くのとでは全然違う.「次にこうするから今はこういう実装をしておけばOK」といった意思決定ができるになる.

以下の優先度の話にもつながることだがRoadmapを作るといかに「やれることが少ないか」が分かる.(略)

https://deeeet.com/writing/2020/10/07/internal-platform-product-management/ より。

組織とプラットフォーム (基盤) は、提供者と受益者の関係性が二面的であったり曖昧であったりする点に共通点を見出すことができる。

上記例では各メンバーを顧客としたが、同時に開発部署を作るのも各メンバーであって、どちらかのペルソナだけを持つわけではない。 これは社内プラットフォームにも言えて、開発者と利用者が完全に分断されているケースのほうが珍しいだろう。

個人のキャリア形成という文脈では受益者という立場が強く出るだろうし、マネージャーに近い役割を負う人は提供者という立場の割合が大きくなることが想像できる。

ロードマップがあれば、近い内に解決が難しい問題に直面した時に実は3ヶ月後なら変わる芽がありそうだとか、しばらく解決は難しそうだが積み上がっている課題を見れば納得感はあるのでバックログを片付けることに協力しようとう気持ちになるなど、そういったコミュニケーションをとれる人が増えないだろうか。

また人事評価 (MBO) とは独立して、かつ人事評価の単位より長い時点までのロードマップを立てられると、人事評価のようなモノリシックなシステムを変えることなくメンバーにより遠い未来について思いを馳せる機会が与えられるかもしれない。 それは視座の上昇の機会となり、自己組織化を促すきっかけにならないだろうか。 リーダーであるための視野・視座・視点 - Tech Inside Drecom

正しく作る

という話に還元されそうなので未読の以下を読みたいと思います:

正しいものを正しくつくる プロダクトをつくるとはどういうことなのか、あるいはアジャイルのその先についてn

まとめ

  • 冒頭に挙げたdeeeetさんのエントリは良いことが書いてある
  • 組織運営も同様にプロダクトマネジメントの手法やベストプラクティスが応用できないだろうかと考えた
  • その考えに則ると、ロードマップの策定は効果が見込めるのではないか