新規Webサービスにおける言語選定について
- #Engineering Philosophy
- #Product Development
新規Webサービスにおける言語選定について
新しくWebサービスを作る際に、プログラミング言語の選定というのは重要な判断になると思います。
個人で開発するサービスであれば、自分がもっとも馴染みのある言語を採用することが多いかもしれません。
あるいは、気になっているけど中々業務では触る機会がない言語を独学で勉強して採用することもあるかもしれないですね。
一方で、会社のサービスとして提供したり、そのサービスで起業を考えていたりする場合、言語選定はとても重要です。
今回は技術面とそれ以外の面から言語選定について、私の考えをまとめてみたいと思います。
※バックエンド開発に限ります。
技術の側面
技術の側面を考える上で大切なのは拡張性だと考えます。
例えば、大規模開発が前提だったり堅牢さが求められるケース、PoC的に開発するサービス、サブシステム的な役割を担うサービスではそれぞれ求められる要件が違います。
現在、一般的に使われているWebバックエンドの言語は Java, PHP, Ruby, Go, Python, Nodejsあたりが多いと思います。
SES系ではJavaが好まれる傾向があり、Web系ではRubyやPHPなどのインタプリタ言語の採用が多いと感じます。
昨今では、Web系企業でもGoやKotlinのような静的片付けの言語が選ばれることも多いと感じます(今回書くのはこのあたりです)
今回のケースでは、新規Webサービスという前提のもと
- 少人数開発
- スピード重視
- 新しい機能の追加と廃止が激しい という観点で考えてみましょう。要するにスタートアップの初期フェーズのような状態です。
私自身、実際にスタートアップの初期フェーズの技術選定に関わった経験があり、 そして数年後に失敗したなと感じた経験があります。そのことに注目して書いていきます。
当時のロジックとしては、
- 少人数だからできるだけシンプルな言語が良い
- スピードを重視したいからインタプリタ系の言語の方が楽
- 癖のない言語を使いたい(触ったことがなくても他の言語の経験があれば書けるような)
という理由でPythonを選択していました。
また、FWにはWebアプリケーションにおけるフルスタックのフレームワークであるDjangoを採用しました。
これはRubyならRuby on Rails, PHPならLaravelと言ったところでしょうか。
初期フェーズの開発速度はかなり出ます。
初期フェーズは基本的に新規機能の追加しかありません。多少の修正があったとしても基本的には付け加えていく思考が強いです。 そのためサービス開始から3年くらいは特に不満なく開発を進めることができます。
余談ですが、多くの場合インタプリタ言語だからといってパフォーマンスが悪いという懸念はほとんど考える必要はないです。
私も最初はインタプリタ言語に対して処理速度のパフォーマンス面は懐疑的なところはあったのですが、よっぽど高パフォーマンスを求められるケースを除いて言語レベルでのパフォーマンスを考慮する必要はないと考えます。(Webの場合です。ミドルウェアなどは関係します。そもそもWebサービスの時点でネイティブアプリより速度は落ちるため速度パフォーマンスを求められることは稀だと思っています)
Webサービスの開発は、多くのミドルウェアを利用します。通常これらは自前で実装することはなく、オープンソースやライセンス契約をして外部のものを利用することがほとんどです。
そして、パフォーマンスに強く影響するのはこの部分であることが多く、工夫次第でインタプリタでも十分に速度パフォーマンスレベルを上げることは可能だと考えています。
話を戻します。
サービスの開発から3-4年が経過すると、機能のアップデートや削除などが頻繁に発生するようになります。 私が所属していた企業でもこのあたりから頻繁に追加と削除が行われるようになっていきました。
設計次第と言えばそれまでですが、インタプリタ言語で型付けが弱い場合、微妙な型の違いや関数の型が決まっていないため曖昧さが増し、実装スピードが低下するということが発生します。
まさに技術負債が芽を出してきたタイミングです。 この状態に陥ると大規模なリファクタリングをするか、少しずつ関数に切り出して整理していくという方法くらいしか取れなくなります。
どちらにしても、時間がかかる割にサービス品質は直接的に向上しないため無駄な工数がかかることになります。
私は、こういった背景を経験したこともあり、初期の開発速度やトレンド重視で安易にインタプリタ言語(型付け弱め)の技術選定を行うことに批判的です。
むしろ、機能の追加と削除が激しいからこそ強力な型付けがうまく作用するケースも多いと思います。
また、型付けが強い言語を利用した場合、抽象化が行いやすいです。 抽象化設計を初期フェーズで行うことで、機能拡張の実装に制約をもたせることも機能追加・削除が多発する環境では有効だと考えます。
それ以外の側面
言語選定をするときに、直接的な技術以外の面も気にする必要があります。
例えば、採用に関して。 会社のサービスとしてシステムを構築する場合は一人で構築することはほとんどありません。 そのため、採用面を気にする必要があります。
人気な言語や実績のある言語は採用に強いことは言うまでもありませんが、あえて新しい技術を取り入れることで新技術に関心の高い技術者を獲得するという考え方もあるでしょう。
エコシステムも気にしたいところです。
例えばJVM系であれば資産が莫大なため、エコシステムは成熟していると言えます。 スタックトレースが出た場合も検索したらすぐに原因が突き止められるでしょう。
一方でそこまで採用実績のない言語やFWの場合はエコシステムが発達していないことも多く、実現したい機能のライブラリなどが整備されていなければ自作する必要があったりもします。
あるいは利用していたライブラリがメンテナンス終了し、代替ライブラリが見つからないということもあるかもしれません。 このあたりの工数は馬鹿になりません。
最後に
今回は、新規Webサービスの言語選定について考えてみました。
現段階での私の意見としては、成長を前提とするサービスであれば、強い型付けの言語を採用するのが将来的に幸せになると思います。
Railsのような開発速度が出るFWを採用するメリットも捨てがたいものではありますが、技術負債は溜まりやすい傾向にあると思います。 システムが成長していゆくにつれ、負債を消化していくことは難しくなってゆくため、設計や実装ルールが整備されていない段階で(例えばPoCの延長線上で本番ソースが更新されてゆくみたいな)推し進めてしまうと、将来的な開発速度が遅くなる懸念もあります。
また、昨今の静的型付けの言語は型推論やジェネリクスの進化のおかげで、開発速度も出やすくなってきていると思います。
モノリシックな構成からフロントとバックを分ける構成も一般的になってきているため、フルスタックのフレームワークによる速度重視の開発から、負債を溜めない健全なシステムを作るという方向性へパラダイムが移りつつあるのではないかと感じます。
余談ですが、直近でバックエンドの技術選定をした際にイマイチ腑に落ちなかったのですが、サーバーサイドKotlinという選択肢はかなりいいかもしれません。(最近Kotlin触っています)