CureAppは「アプリで治療する未来を創造する」

井上真吾氏:みなさんおはようございます。さっそくですが「複数プロダクトで利用する共通ライブラリの戦略と運用経験」という題でトークさせていただきます。よろしくお願いします。

まず自己紹介になります。井上真吾と申します。株式会社CureAppというところでチーフエンジニアをやらさせていただいています。言語としてはTypeScriptやNode.js、要はJavaScript系がとても大好きです。サーバもフロントもWebもアプリもという感じです。言語処理系を読んだり、ASTなどをいじったりするのが大好きです。

株式会社CureAppについて紹介をさせてください。株式会社CureAppですが「アプリで治療する未来を創造する」ということで、「治療アプリ」と呼ばれるソフトウェア医療機器を作っている会社になります。

具体的にどういうプロダクトなのかみたいな、詳しい説明をしに来たわけではないので「実際にCureAppが成し遂げること」としては、医療費の問題が今後続々と増えてくると思います。

その医療費の削減だったり、医療格差を埋めることなど、日本の医療の世界はいろいろな制約とかがあったりするんですけど、その規制緩和に合わせて、日本発のイノベーションを生むことを目指しています。

主に生活習慣病を題材に、ニコチン依存症や非アルコール性脂肪肝炎、高血圧などを扱っています。ヘルスケアの事業も別途やっているんですけど、そのへんの詳しい話はもしよかったら懇親会やAsk the speakerコーナーで聞いてもらえればと思います。

最近では治験というものがアルバイトなどであると思うんですけど、弊社のアプリで治験をやっていまして、その結果が出たので、記者会見をしたり、22億円ぐらいの増資を受けたり、評価や注目をいただいている企業だと思っています。

CureAppの技術スタック

会社紹介はそれぐらいにして、技術スタックとしてはJavaScriptやTypeScriptで書いています。ちょっと小さくて見にくいかもしれないですが、SPAをクラウドフロントに配布してAPIサーバはAPIGatewayとLambdaを使って、仕組みを作っている感じになります。

主に使用している技術としては、すべてJavaScriptやTypeScriptで書いています。アプリも作っているので、アプリに関してもJavaScriptで作っています。

本題ですが、このディレクトリ名たちを見て、みなさんはピンと来るかと思います。たぶん、みなさんのプロダクトに1個ぐらいこんなフォルダがあるんじゃないかと思います。うちのアプリもあります。紹介できる限りは4個なんですけど、他にもいろんなプロダクトを作っています。

次のプロダクトに移って書いているときに「あれ? これ前も書いたな」みたいなことがけっこうあって、シンプルなユーティリティ関数、例えばゼロフィル、数字の手前に0を入れる処理とか、そういったシンプルなものあたりから始まったんですけど、他にも共通になり得るものはたくさんあるかなと思っています。

例えば画面や、認証・認可まわりなど、ビルドやデプロイの設定だったり、プロジェクトの大枠の技術スタックは似ているので、例えば「ボイラープレートを作ったらいいんじゃないか」とか、他にもいろいろとありました。

前にも作ったし、もう1回同じものを作ってまたエンバグして、プロダクトがリリースされるまでの期間がかかります。バグを直して確認して、もう1回バグを直して、「各プロダクトで同じことをやっているな」と、とても思いました。

なので、あらかじめ1回踏んだバグはライブラリにして、他のプロダクトではバグがないライブラリを使ってプロダクトを開発すれば、時間の節約にもなるし、ライブラリを集約していくことで、プロダクト開発のコアに割かないといけない時間が生まれると思って、ライブラリ化の作成を始めました。

昨日数えてみたんですが、Node.jsなのでnpmというツールを使ってライブラリを公開します。OSSになっているものもあるんですけど、社内だけで使えるパッケージがほとんどです。そのライブラリのリリースペースを数えてみたんですが、この1年で仕事で473回、自分の趣味のOSSで196回のリリースをしていました。

たくさんのリリースを経て得た成功や失敗

これだけリリースをしてきたからこそ得た失敗や成功もあったかなと思っているので、今日はそういうお話をさせていただければと思います。

そのライブラリを作り始めるときに、「こういう要件のアプリです」と決まって、「じゃあ作るぞ!」ってなるんですけど、そのプロダクトを作り始める前に先に「こういう要件なんだから、こういうライブラリが必要なはずだ」みたいなことを考えながら、いきなり作り始めて「実際にプロダクトを作り始めて、そのライブラリを入れてみよう」となると「ちょっと要件とマッチしていない」みたいなことが発生したりします。スライドのような感じでライブラリ先行で作ると失敗しやすいかなと思います。

こんな感じで起きた失敗と、どういう学びを得たかをつらつらと並べていこうかなと思います。

こうした反省を活かして、今度はプロダクトの中で使いながらなるべくライブラリになるように汎用的にプロダクト固有の知識がなるべく混じらないようにと切り分けながら作っていって「プロダクトが完成した。よしライブラリを出してみよう!」となったときに、なるべく気を付けながら書いていっても、そのプロダクトの都合がどうしても混じってきてしまって、ドッグフーディングをしすぎないように早めに分離をするといいかなと思います。

ボイラープレートはなるべく作らないほうがよかったかなと思います。その各プロダクトでベストプラクティスになっているコードを公開しておいて、それを参考にすることだったり、必要であればライブラリ化をする。プロジェクト全体の雛形は作らないほうがいいかなと思いました。

アップデートをすると「こういう機能の変更やこのバグが直ったよ」みたいなことを共有するコストが掛かって、そこにライブラリを作っている人はみんなそうしているんですけど、それを使っている側の人はぜんぜんキャッチアップできない。

それでその情報格差がどんどん生まれていったので、リリースの通知は全部自動化して「このバージョンでこれがリリースされました」みたいなリリースノートをちゃんと書いたりして、なるべくあとからでも見返せるし、リアルタイムでも気が付ける工夫をしていました。

1つのプロダクトの都合で機能の追加や使用の変更をして、他のプロダクトにとって都合の悪いものになってしまったこともありました。これに関してはReactやNode.js、VimなどのOSSにのっているんですけど、rfcsみたいなリポジトリがあります。

ここで仕様を議論するという「Request for Comments」という略で「rfcs」なんですけど、ここまで大げさなことはやらずとも、こういう大きい変更を加えたいという意表を立てて、そこでその各プロダクトのエンジニアで議論しながら「どうなるのがみんなにとって都合がいいか」と練ったりしていました。

たぶん自作でライブラリを作るときに一番の強敵はドキュメントだと思っています。ここを蔑ろにしてやってしまうと、作っていた人や当時使っていた人だけが知っていて新しい人がぜんぜんついていけないってなっちゃうので「ドキュメントとかを書くことも含めてライブラリを作ることなんですよ」というのをとても学びました。

OSSをリスペクトしながら運用していこう

キャッチアップすることに関しては、モブプロを定期的に開催していました。

単にハウツーではなくて「なんでこのライブラリがあるのか?」みたいな思想も共有して、みんなとコードを書いていって、そのライブラリの中身や思想を知ってもらったり、こうやって登壇をしてみなさんからフィードバックをもらいながらやっていました。

あともう1個。やっぱりそれでも日々プロダクトの開発をしていると時間って取れないので、合宿をやってプロジェクトの開発じゃなくて「ライブラリだけをやる合宿」とか「ドキュメントを書く合宿」みたいなのをやっていました。

そろそろお時間ということでまとめに入っていきます。こんなことをやってみた結果、プロダクトが違うから、同じ技術で同じスタックなのに縦割り感があったところが薄らいでいきました。

最後になるんですが、こういうライブラリの戦略として作ってちゃんとコストに対してペイするかというところは事業の優先順位にもよるので、そこも考えながら、やり方としてはOSSをリスペクトしながら運用していくと良いライブラリやエンジニア組織になっていけるんじゃないかと思っております。

「We are hiring」ということで、ご清聴ありがとうございました。

(会場拍手)