Kibela開発における技術選択の指針を全部教える。必要十分に新しい技術を維持するための考え方
サービスの立ち上げや機能追加時には、どのような技術をどの観点から選択すればよいのでしょうか? 自社サービス「Kibela」の実例を交えつつ、ビットジャーニーの井原正博さんがエンジニアと経営者の両視点から「技術選定」を考えます。
Yahoo! JAPANやクックパッドのエンジニアを経て、現在はビットジャーニーで代表を務める井原正博(@ihara2525)です。プライベートで超長距離のランを楽しむ傍ら、情報共有ツールKibelaの開発・運営を手がけています。
Kibelaについては、その立ち上げにあたってサービスを考えてリリースするまでのフローを以前に書きました。今回は、サービスの技術選定をテーマに、Kibelaを成長させるさまざまな段階でどのような選択を行ってきたか、具体例を交えながら紹介できればと思います。
新しくサービスを立ち上げたり既存のサービスに機能を追加したりする際に、どのような技術で実現するかを技術選定するステップがあるかと思います。このとき、どのような観点からどのような技術を選択すべきでしょうか?
難しい問題ですが、純粋にエンジニアとしての視点であれば世の中に良い情報もたくさんありますので、ここでは今まで開発を行ってきたエンジニアとしての気持ちに加えて、経営者としての視点・気持ちからも考えてみたいと思います。
使って楽しい技術を「必要十分に新しい」状態に維持できるか
まず、エンジニアとしての視点から考えてみます。何よりも自分が「使っていて楽しいか?」「楽しく開発できるか?」という点が挙げられます。
この「楽しい開発」にもいろいろな要素があり、何を「楽しい」とするかは人それぞれでしょう。
- その言語らしく書ける
- よく言われる「Rubyをキメると気持ちいい!」みたいなやつです(古い)。
- 使っている人が多い
- コミュニティが大きいと情報も得やすく、困ったときにはインターネットの力を借りて、さくさく開発を進めることができます。
- 使っている人が少ない
- 逆にコミュニティが小さいと濃く密な話ができるでしょう。あるある話とか楽しそうです。
- この先も必要とされるであろう技術
- 未来がある技術には、エンジニアとしても未来があるように感じられます。「この技術使っててもな~」みたいな気持ちで開発するのはつらそうです。
つらそうなシチュエーションにもいくつか考えられますね。
- 利用者が増えている新しい言語を使って開発したいが、利用者が減ってきた古めの言語を使わないといけない
- フレームワークの新しいバージョンがあるのに、古いバージョンで開発しないといけない
- 詳しくなったところで社内でしか使えない独自フレームワークやライブラリを使わないといけない
使っていて楽しくない技術よりは、使っていて楽しいものを使いたい。これはエンジニアとして自然な気持ちではないでしょうか。「使いたい」という気持ちは大事です。
自分以外のエンジニアも使える技術か?
自分が「使いたい」という気持ちは大事ですが、一人で開発しているのでなければ他のエンジニアにも「使いたい」という気持ちがあるわけで、それぞれが好き勝手に技術選定していると全体的にバラバラで、一人しか触れない状態になってしまうリスクがあります。
例えば、Rubyをメインの開発言語としている組織であれば、知識の共有や人材の流動性といった面からも、基本的にはRubyで開発することが最初の選択肢となるでしょう。
「いや、どうしてもScalaで開発したいんです」となると、自分が「使いたい」という気持ちだけで選択することは難しく、「なぜScalaで開発すべきなのか?」という明確な理由が必要です。また、自分以外に開発できるエンジニアを増やして、メンテナンスできる体制を作ることも必要になるでしょう。
自分で好きなように技術を選定して開発した結果、退職等でメンテナンスを難しくしてしまうような事態は避けたいですね。
世の中で主流か? 主流になりそうか?
新しくイケてそうな技術が日々生まれていて、見ていると「使ってみたい!」という気持ちになります。新しいものが好きで試したい気持ちは非常によく分かります。
世界は日々進歩していますから、昨日より今日の方が、今日より明日の方が良くなっているはずです。もっと簡単に分かりやすく書けるようになっていたり、もっと速く軽く動くようになっていたり、もっとリソースを使わないようになっていたり。
しかし、ここはちょっと落ち着きたいところです、確かにその技術は良さそうだし、今は話題になっていますが、来年も再来年もずっと使われて主流になっていくでしょうか?
業界の流れが速い中でバズった技術に飛びつき、まだベストプラクティス等もない中を頑張って導入したものの、一過性のブームで人気も下火になり、利用者が減って、開発が止まってしまったり、メンテナンスされなくなったり。その結果、「何で導入したんだっけ? やらなきゃ良かったのに」となってしまうとつらいものがあります。
世の中のWebエンジニアなら誰もが知っているような非常に大きな会社が運営・開発するサービスやライブラリであっても、閉じてしまったり開発を中止したりすることがあります。ちょっと考えてみても「あ~、あったね~」みたいなサービスや技術、バズワードはたくさんありますね。
必要十分に新しい技術を維持する難しさ
ここまで見てきたように、基本的には新しいものを使う方が効率は良くなっているはずですが、新しい技術が次に主流になるかどうかを見極めるには高い眼力が求められます。新し過ぎたり、リリースされたばかりのものには、次のようなリスクがあるかもしれません。
- リリース直後のため、安定していない
- 現実の世界であまり検証されていないため、未知の不具合がある
- 利用者が少ないため、情報も少ない
- 将来も使われるものなのか、新し過ぎて判断できない
最新のものを利用したいという気持ちは個人的にはとても分かるものの、ここでは「必要十分に新しい」という視点が必要だと考えます。ちょっと我慢して、ある程度安定しているものを利用するのもよいのではないでしょうか(私が若い頃はもっと最新に最新にと突っ込んでいっていた気がするので、何も偉そうに言えませんが……)。
ただし、ちょっと我慢するつもりが、ずっと放置してしまい、必要にも十分にも新しくない状態になってしまわないよう注意が必要です。新しい技術のキャッチアップが難しかったり、試すことができる人がいなかったり、そもそも継続的に開発されていなかったりした結果、サービスや機能が誰も触れない「技術的負債」になってしまうリスクもあります。
新し過ぎも古過ぎもしない「必要十分に新しい」状態を保ち続けることが大事になるでしょう。
自分の状態に応じて相対化される技術選択
エンジニアとしての視点で技術選定について見てきましたが、自分たちの状態によっても選択肢が変わってくると思います。
例えば、会社を作ってサービスを立ち上げようという段階で重視する技術選定の軸と、ある程度安定したサービスの軸では、全然違うものになるでしょう。
- 立ち上げ期のサービス
- 立ち上げなのでとにかく早く作れることを重視し、使える技術でやる
人が少ないので持ちモノも少なくする - ある程度安定したサービス
- 関わる人も増えているので、ある程度いろいろな技術を試すことができる
保守性を高めつつ、技術的な負債にならないよう、新しいものも取り入れつつ、少しずつアップデートする
上記に加えて、抱えるサービスの数や、展開するプラットフォーム等によっても変わってくるでしょう。
これから起業してサービスを立ち上げていこう、という段階でマイクロサービス化を検討することはなさそうです。これから作ろうしているものに価値があるかどうかも分からない状態ですし、サービスも一つしかないのだから、まずはモノリシックに「なる早で作りましょう」となります。
一方、サービスが成長して大きくなり、別のサービスも立ち上げて、複数のサービスで共通の基盤があった方が管理しやすくなってくると「じゃあこのタイミングで、認証まわりや課金まわりを分離しましょうか」という話になるはずです。
早まってやり過ぎないように、しかし遅過ぎて手遅れにならないように。この見極めが非常に難しいところです。絶対の解があるわけではなく、自分たちの状態や技術を常に確認しながら、やるべきタイミングかどうか見極めましょうという話になってしまいます。
Kibelaではどのように技術を選択してきたのか?
Kibelaは、2015年に私が一人で開発を始め、現在はエンジニアが6名ほど、全体で10名程度のスタッフに関わってもらいながら開発を続けています。これまでどのように技術選定を行ってきたか? 今後どのように技術選定を行っていくか? 具体的に考えてみます。
早く作れる使い慣れたRailsを選択した立ち上げ期
自分でサービスを立ち上げていくので時間的なプレッシャーがあるわけではなく、また開発者も自分一人しかいないので、好きに技術選定を行うことができました。しかし、早く立ち上げたいという思いはあったので、自分が使い慣れていた技術を選択しました。
プログラミング言語はRuby、フレームワークはRuby on Rails、インフラはAWSといった、比較的オーソドックスなものたちです。
本当は、それまで本格的に使ったことがなく、他の言語に比べるとRubyに比較的近いとされるElixirで開発してみたい気持ちもありました。しかし、会社を作ってサービスを立ち上げるという、ただでさえ初めて挑戦することが多い中、さらに不確定な要素を増やしたくないということで、このような選択になりました。
このとき重視したポイントは以下の通りです。
- 使い慣れていること
- サービスのことも考えないといけないので、手になじんだ道具でさくさく作りたい
- 新しく学ぶことが少ないこと
- エンジニアとしてはつまらないかもしれませんが、早くサービスを立ち上げたい
- 早く作れること
- 慣れもありますが、言語・フレームワーク・インフラの生産性がそもそも高い
- 使える人が多いこと
- 将来的にエンジニアが必要になったとき、開発できる人が多く、人を増やしやすい
- ある程度、枯れていること
- まだ新規性が高くて地雷を踏みまくることや、互換性がない変更がない
- 情報が多いこと
- 困ったときに事例を探しやすい
複数人での開発になりES2015やReactを導入
一人でコツコツと開発を進め、技術的に新しい要素はそれほどないものの、サービスの基盤ができあがってきました。リリースはまだ先ですが、ありがたいことに開発に関わる人が少し増え、それまで使っていなかった技術を取り入れる時間や人を少しだけ捻出できるようになりました。
当時、フロントエンドはRails標準のjQueryとCoffeeScriptで書いていましたが、これからエディタの作り込みが必要になることや、そのころReactの人気が高まってきていて記事もよく見かけたことから、ES2015(ECMAScript 2015)とReactを導入します。
このとき重視したポイントは以下の通りです。
- これから必要になる開発に向いていそう
- エディタやその他の部品をjQueryで作り込んでいくのは、けっこうつらそう
- 標準となる仕様(ES2015)ができてきた
- 本流があればそれに乗っかる
- 今後よく使われる技術になりそう
- Reactは今でも使われていて良かったです
- 使っている技術が若干古くなってそう
- もう少しモダンなものを使いたいというエンジニアの気持ち(技術としてのjQueryやCoffeeScriptが果たしてきた役割や今でも果たしている役割は大きいと思います)
なお、技術的にどのようにES2015やReactを導入していったかは、次の発表資料に簡単にまとまっています。よろしければご覧ください。
技術に強めなエンジニアの参加でTypeScriptやGraphQLを導入
さらにサービスの開発は進み、リリースも見えてきました。技術に強めなエンジニアも参加してきたため、技術的なチャレンジも増えてきました。技術的に「やりたい」という気持ちがあり、実際に「それをやれる」という状態です。
ここで技術選定において重視するポイントは、上記の複数人での開発時とそれほど変わりませんが、もう少し攻めた技術選定を行っていけます。例えば、次のような技術を選択しました。
- 静的型付けのために、TypeScriptを導入
- APIとして、Railsで普通に作るとRESTful APIになりそうなところ、GraphQLを導入
- ネイティブのアプリケーションの開発を、React Nativeで行う
iOS/Androidアプリケーションの開発は、理想的にはそれぞれのプラットフォームが提供している標準の技術(iOSならSwift、AndroidならKotlin)を利用したいところですが、それぞれに担当者を充てられないため、React Nativeを用いて両プラットフォームに対応できるようにしました。Web側でReactを利用しているため、読める人が多いということもあります。
それほど難しいことをやっていないので、まずはReact Nativeで両プラットフォームをサポートすることを重視したこともあり、将来的にそれぞれのプラットフォームに特化したエンジニアがいる状態になれば、標準の開発方法で作り直す日が来るのではないかと思っています。
このとき重視したポイントは以下の通りです。
- 技術的にもう少し攻めてみる
- 攻められる能力があれば、技術的に面白いことをやることで開発に対するモチベーションも高まり、社外への技術的なアピールにもなる
- 技術的負債になる可能性を認識する
- 導入した技術が廃れてしまったり、担当者が退職するかもしれない
- 攻め過ぎはしない
- 攻めれば攻めるほど技術的負債になってしまうリスクも上がる
- 新しい価値を提供する最短の方法を探す
- ネイティブのアプリケーションは標準の技術で開発したいが、まずはリリースを重視する
ここでは「複数人での開発時」のスタンスは保ちつつ、技術的負債に関する項目などを追加しています。
技術的にある程度攻めた選択をする場合、生産性が高まる可能性がある一方、同様に技術的負債になる可能性もあると思っています。例えば、その技術の開発や人気が先細ってしまう場合や、特定のエンジニアの能力に依存して成り立っていたものが退職等により強い人がいなくなってしまうような場合です。
技術的に新しかったり、面白そうだったりして「触ってみたい」という技術を導入することで得られる生産性の向上や、気持ちの高まりは確かにあります。一方で、技術的負債のリスクがあることも十分に認識しておく必要があります。
なお、GraphQLについては、弊社のエンジニアがエンジニアHubでも入門記事を書いていますので、こちらもよろしければご覧ください。
経営者としての視点から
ここからは視点を変えて、サービスを運営する経営者としてどのような技術選定を行うか、あるいはエンジニアリングが分からない経営者にとってどういった技術選定をエンジニアに行ってもらえると分かりやすいか、について考えてみます。
おそらく、経営者側から「そろそろこういうアーキテクチャに変更した方が良いんじゃないか」「この技術を導入した方が良いんじゃないか」という提案が起きることはそうないと思います(バズワードに影響されることはありそうですが)。
そのため、エンジニアとして最適な技術選定を主張していくことは非常に大事です。その選択が、サービスや事業の未来も決定する一因になると思います。
その技術は早く作ることができるのか?
大企業とスタートアップでは時間の流れ方も違い、開発に求めるスピードも若干異なるかもしれませんが(大企業がのんびりしているわけではありません)、開発が速く進むことを嘆く会社はあまりないでしょう。開発もサービスも、速いは正義です。
というわけで、その技術選定によって開発はスピードアップするのか、少なくとも遅くはならないのか、は気になるところです。エンジニアリングが全く分からない経営者の場合、開発の質やソースコードの品質等にはそれほど興味はなく、開発が予定通りに進んでいれば良い、ということもあるかと思います。
そうすると「新しいアーキテクチャを導入したい」となったときに、導入するコストはかかるが、開発のスピードはそれほど変わらない。しかし、エンジニアとして少し先の未来を考えると、そろそろこの辺で設計を変えておかないと将来の開発が難しくなる。しかし、経営者は分かってくれない。という、なかなかつらい状況になることがあるかと思います。
エンジニアは、サービスを継続して開発し、世の中に価値を提供し続けるためにエンジニアリングを行うわけです。その将来を危うくしないための技術選定を自由に行うことができないのは残念ですが、「開発のスピードは落とさないでほしい」という経営者の気持ちもあるでしょう。
この技術選定を行うことで超短期で見ると確かに開発効率は落ちるかもしれないが、中長期で見たときに少なくとも現状の開発速度を保つために「今これをやるべき」という話を何とか伝えていくことが大事になるでしょう。
その技術はどれくらいのコストがかかるのか?
技術選定を行った結果、何か「新しいものを導入しよう」となったとき、どれくらい人やお金のコストがかかるのかも気になるところです。
会社の状況によって、ある程度は技術や人に投資できたり、とにかく現状では支出を増やせなかったり、いろいろあると思います。とりあえず、まずはその技術を使うことによって得られるものがどれくらいあり、コストがどれくらいかかるのかを伝えてもらえると助かります。
私の場合は、ある程度はエンジニアリングを理解しているので、かけるコストに対して得られるもののバランスを何となく理解できていると思います。しかし、それが分からない経営者に伝える場合、特に技術的なメリットを説明するのはなかなか難しいですよね。金額的な価値に換算できるとまだ分かりやすいのですが……。
その技術は事業に対して何の価値を生み出すのか?
前述のように、その技術選定を行うことで「何がどう良くなるのか?」を伝えていく必要があります。
しかし、例えば「マイクロサービス化すべきだ」という選択をしたい場合、それを経営者に伝えて実施するには、それなりに高いハードルがありそうです。「サービスの責務を適切に分け小さく保つことで保守性が上がります」「サービスを適切なフレームワークや言語で開発できるようになります」「エンジニアを採用しやすくなります」等々。
「今やるべきなのか?」「どれくらいの人や時間がかかりそうなのか?」といった説明をすればそれなりに意味は分かると思うのですが、必要なコストや得られるものとあわせて「事業の成長にどう関わるのか?」「それは事業価値につながるのか?」についても説明してもらえるとありがたいと思います。
また、「やりたい」という気持ちから、良い面だけを伝えがちになってしまうかもしれません。先のマイクロサービス化の話をするのであれば、良くないかもしれない面も伝えてもらいたいところです。例えば、インフラに関わるメンバーが一人しかいない組織では、日々の運用で手一杯の中でさらにサービスを分割され、見なければいけないサーバーを増やしてしまう選択をすることは難しいでしょう。
技術的には正しそうな選択であっても、会社やチームの状況によって実施できなかったり、現状の事業価値につながりそうにないこともあります。同様に、得られるものと必要なものを、少しエンジニアリング以外にも視点を向けて考えてもらえると、良い相談や選択ができるのではないでしょうか。
Kibelaでは今後どのように技術を選択することになるか
Kibelaは今もまだまだ開発を進めていて、これが落ち着く日が来るのだろうか? という感じもありますが、比較的落ち着いてきたらどのような技術選択を行っていくだろうかと想像してみます。
サービスとして規模が大きくなってくると、その影響を考えたときに簡単にリリースすることが難しくなります。そうすると、攻めた技術選定よりもある程度安定した技術を利用して、安定したリリースが求められるでしょう。
しかし、それでもフレームワークやライブラリ等は細かくアップデートして新しいものに追随していかないと、簡単に触ることができない状態になってしまいそうです。必要十分に新しい技術を取り入れつつ、細かく変化し続けたいところです。
このとき重視するのは以下のポイントです。
- 安定した必要十分に新しい技術を取り入れ続ける
- 小さく変わり続けることで技術的負債を残さない
メンテナンス時に入ったら技術的負債とならないよう
メンテナンス状態に入って機能追加が減っていたり、別のサービスを開発していたりいて、将来的にはKibelaを触る頻度が減っているかもしれません。
そうすると、全く新しい技術を導入することが難しくなっていたり、気をつけないとフレームワークやライブラリのアップデートまで遅れがちになったりしそうです。「安定しているなら触らないでいいじゃん」と言われそうですが、そうすると技術的負債と呼ばれるものになってしまうでしょう。
一方で、安定して提供し続けている大規模なサービスを、そのときの最新技術で完全にフルスクラッチでリニューアルするかというと、それも難しい選択になりそうです。技術的に新しいチャレンジは別のプロダクトで行うことになり、Kibelaというサービスの根本を変更することは難しいのではないでしょうか。
このとき重視するポイントは以下の通りです。
- 新しい技術で作り直すなら覚悟を決めて
- 大規模で安定したサービスを提供できていて、技術的負債にならないのであれば、作り直す必要はない
- 問題が起きたときに解決できる程度の技術は保ち続ける
- 触ることができなくなるとつらい
Railsのバージョン20で動いています、という未来が訪れるのか考えてみると、フレームワークがそのときも継続して開発されているのか? 優れたフレームワークであり続けるのか? 等々あって「正直どうするんだろう?」という気持ちになります。
互換性を保ちつつ、新しい技術で作り直す日が来るのか? ある程度は技術的負債となりつつも、メンテナンスできる状態を保っていくのか? その選択を迫られるときが来るのだろうと思います。
技術的負債とならない技術選定をしつつ、ずっと開発を続けるのは難しい課題です。
エンジニアが楽しく開発し続けるために
経営者としての自分は、エンジニア出身なこともあり、「エンジニアが触っていて楽しい技術であること」を大事にしたいと考えています。
同じように、一緒に関わっているメンバーが日々楽しく開発できているかを考えている経営者もたくさんいるでしょう。楽しくない開発よりは楽しい開発をやっていてほしいですし、自分たちはこの技術選定が正しいし楽しいと思える状態であってほしいです。
一方で、エンジニアとしては、少なくとも今自分たちが考えられるベストな技術選定をしたいと考えています。同じように考えているエンジニアも多いことでしょう。
自分たちが「やりたい」という技術について、エンジニアリングという視点だけではなく、ちょっと広げて「なぜやるのか?」「何が得られるのか?」「どれくらいのコストがかかるのか?」まで考えてみることで、経営者としても非常にありがたい技術選定になるのではないでしょうか。
井原 正博(いはら・まさひろ)@ihara2525