複数の言語で同じWebサービスを実装して技術特性の違いを見てみた

開発合宿運営チームの id:yutailang0119id:maku693 です。はてなでは四半期に一度、技術グループ主導で開発合宿を開催しています(過去の合宿の様子は「開発合宿」カテゴリーにまとまっています)。

2023年4月に実施した開発合宿では、参加者が複数のチームに分かれ、それぞれ異なるプログラミング言語で同じお題のWebサービスを開発しました。言語ごとの特性を比較し、今後の技術選定に生かす取り組みです。

この記事ではその開催レポートをお届けします。

開発言語の特性を理解したい

はてなではたくさんのWebサービスを運営していますが、それらを実装する技術は統一されているわけではなく、プロダクトあるいは構成要素ごとに複数の異なる技術を利用しています。

これは状況に合わせた技術を採用できるメリットがある一方で、採用する技術に関する統一された基準や見解が社内に少なく、新たなサービスを開発する際に毎回改めて技術選定しなければならないというデメリットにもなっていました。

この課題に対する一つのアプローチとして、開発合宿で各技術の特性を理解し、それぞれを相対化することで将来の技術選定の糧にしてもらうことを狙いました。

また、単に複数の言語で同じサービスを実装するだけでなく、開催後の技術勉強会で感想戦を行い、合宿に参加できなかったエンジニアとも知見が共有されるようにしました。

さまざまな技術要素を2日で実装できるお題に

普段なら合宿参加者からお題を募るのですが、今回は上記の目的のため運営がお題を提示し、弊社のラボサービスである「はてな匿名ダイアリー」のようなWebサービスのバックエンドサーバーを実装してもらいました。

これは記事の権限管理やログイン・ログアウトといった機能があるため単なるCRUDよりやや高度になり、具体的にはGraphQL API、OpenID Connect(OIDC)によるログイン・ログアウト、セッション管理といった機能の実装が必要になります。

何をどこまで実装してもらうかは運営チーム内でも議論がありましたが、2日という短期間で実装できること、弊社のサービスで多く採用されている機能であること、さまざまな技術要素が必要でそれぞれの言語の特徴が出やすいだろうということから、このお題となりました。

参加チームやコミュニケーションでの工夫

合宿は4月17日(月)から18日(火)にかけて実施しました。参加者は18名で、開発言語ではTypeScriptが2チーム、Goが2チーム、ScalaとRubyが各1チームの計6チームです。フレームワークやアーキテクチャの選択は各チームに任せましたが、複数チームあるTypeScriptとGoでは選択技術に差が出るようチーム間で調整してもらいました。

参加者が本質的な開発に集中できるように、フロントエンドの実装や、OIDCプロバイダ、GraphQLスキーマを含むテンプレートリポジトリについては事前に運営で用意し、各チームにそのままフォークして使えるようにしました。

また、はてなではフレキシブルワークスタイル制度を導入しているため在宅勤務中心で働くメンバーが多く、会場として以前も利用したoViceを用意しました。普段とは違うメンバーと交流することも目的の1つですから、oViceは大きなサイズのプランを選択して、はてなスタッフは誰でもふらっと立ち寄れるようにしました。

さらに、各チームにははてなメンバー全員が見ることができるScrapboxプロジェクトに積極的にメモをとってもらうようにし、当日参加できない人でも合宿の雰囲気を感じ取れるようにしました。

順調に開発が進んだ合宿当日

合宿中には、運営からの連絡と、参加者から進捗と困り事を共有する場として、oVice中央に集まって昼会と夕会を行いました。

夕会の様子

1日目の夕会で各チームの進捗を確認したところ、主要な機能については実装が終わっているか、終わる目処が立っている状況でした。そこで運営から各チームに「トラックバック」機能の追加実装を依頼しました。これは急な仕様追加に対応できるかを見るため、事前に準備していたお題でした。

最終的には当初に提示した機能だけでなく、2日目の夕会までに全てのチームがトラックバックについても実装を終えました。さらに時間が余ったチームは次のような機能を追加するなど、それぞれ独自にアプリケーションをブラッシュアップしました。

  • Dataloader
  • 構造化ログ出力
  • OpenTelemetryメトリクスの出力

技術勉強会で「成果物を見る会」を実施

はてなでは毎週木曜に技術勉強会を開催し、多くのエンジニアが参加しています。合宿開催直後には、CTOの id:motemen とチーフエンジニアの id:cockscomb が成果物を見ながらさまざまな切り口でコメントし合い、技術ごとの違いを明らかにするという形で「成果物を見る会」を開催しました。

当日は参加者との掛け合いもあり、大盛り上がりとなりました! 感想戦の全てをここで紹介することはできませんが、抜粋を一部紹介します。

  • 厚めのフレームワークだと設定より規約的な構成になりやすい。薄めだと何をしているか把握しやすい一方、基盤部分の手書きが増える
  • GraphQLに関してはどの言語でも道具は揃っており、似ている部分も多い
  • 全てのチームでSQLを書いていない
  • PrismaやRailsはテスト用の道具が比較的充実している
  • 体験に関しては言語ごとの差が激しい。型の有無、IDEやGithub Copilotとの相性、レールに乗ったときの気持ちよさ、レールから外れたときの難しさなど

なお、成果物を見る会についても社内Scrapboxにページを用意し、技術勉強会に参加できなかったメンバーがあとからキャッチアップしたり、今後の技術選定の際に参照できるように記録を残しました。

開発合宿を終えて

はてなでは、これまで何度も開発合宿を開催してきました。今回は、初めて参加者全員で共通のお題に取り組み、比較する形式で開催しました。当日参加したエンジニア以外も「成果物を見る会」を通じて楽しむことができ、満足度の高い開発合宿となりました。再開催の要望も上がっています!

今後も今回のようなお題に限らず、普段の業務ではできない取り組みを実現する場として、定期的に開発合宿を開催する予定です。ぜひ、はてなで一緒に働いて、開発合宿に参加してみませんか? 運営に協力してくれる方も募集しています!

株式会社はてなの採用情報はこちら

プログラミング言語ごとの使用ライブラリ

最後に、今回のお題で言語ごとに利用されたライブラリの一部を紹介しておきます。

TypeScript

  • Express + express-openid-connect, Next.js + NextAuth
  • GraphQL Yoga, Apollo Server
  • GraphQL Code Generateor
  • Prisma
  • prisma-fabbrica

Go

  • net/http, Echo
  • gqlgen
  • go-oidc
  • ent
  • ginkgo, testify

Ruby

  • Ruby on Rails
  • OmniAuth
  • GraphQL Ruby
  • RSpec
  • FactoryBot

Scala

  • http4s
  • Sangria
  • Slick
  • scalatest

はてなでは、技術に対する向上心を持つ仲間を募集しています