エイチームコマーステックでエンジニアをしている北村です。
昨年3月からペットフードブランド「Obremo」の新規開発に携わっています。
Obremoは「ペットを家族のように大切に思う人々に対し、個々に寄り添った商品と情報の提案を通じて、家族の絆を深める健やかで楽しい日々を提供する」ことをコンセプトにしたペットフードブランドです。
品質にこだわったペットフードの提供はもちろん、フード診断を通じてペットのコンディションに適したフードプラン提案が特長のサービスです。
2021年8月にローンチしたObremoですが、立ち上げにおいて僕は、Obremoのバックエンドやインフラを中心としたシステム設計を担当しました。
エイチームグループでは、これまでRailsをつかったREST APIでの開発がほとんどでしたが、Obremoでは今回、(子会社のエイチームコマーステックとして)はじめて本番環境でGraphQLを採用し、GraphQLエンジンとしてHasuraを利用しました。
※ GraphQLは、ざっくりいうと「データを問い合わせるための言語」です。REST APIとの違いはこちらが分かりやすかったです。
この記事では、
・Obremoにおける技術選定の考え方
・GraphQL/Hasuraを実際採用してみてどうだったか
についてまとめていきます。
- 技術構成を決めていく際に、何を大事にしたいのかを「技術コンセプト」として持っておくとよい
- 「お客様に一番近いフロントエンドの改修を素早く行える」という技術コンセプトのもと、GraphQLエンジンであるHasuraの採用や、ヘッドレスCMSのStrapiを採用した
- Hasuraはバックエンドの改修コストを下げ、ビジネスロジックの構築に集中できる
- StrapiもといヘッドレスCMSによってエンジニアを介さずマーケやデザイナーだけでLPの改善や制作ができる状態を実現
- Hasuraは、GraphQLバックエンドを素早く構築したい時におすすめ
- 簡単なCRUD(Create, Read, Update, Delete)や権限管理はHasuraに任せられるが、ビジネスロジックは実装が必要な点に注意
- これまでの一般的なバックエンドの構造とは毛色が違うため、エンジニアが慣れるのに比較的時間が必要なことにも注意
これまで他サービスの開発を担当してきて、「一つの改善施策を打つにも、フロントエンドもバックエンドも改修する必要があり面倒...」という場面に何度も直面してきました。
そういった経験から、Obremoでは「皆が優れた顧客体験の実現に集中できるようにするための技術選定」をしたいと考えていました。
そこでObremoでは以下のような技術スタックを採用しました。
立ち上げ時、バックエンドを担うエンジニアの数は約2人で、アプリもWebも開発対象であったため、バックエンドの改修がボトルネックにならないようにHasuraもといGraphQLを中心とした技術構成にしました。
また、Obremoは広告による集客をメインとしており、事業計画上、運用パフォーマンス向上のためスピーディな仮説検証が行える状態が求められました。
そのため、改善が頻繁に求められる広告出稿用LP(ランディングページ)に関しては、エンジニアがいなくてもデザイナーやマーケターがブログ感覚でコンテンツの公開・編集ができるようにStrapiというヘッドレスCMSを採用しました。
今回、GraphQLエンジンとしてHasuraを、ヘッドレスCMSとしてStrapiを採用した点は、コマーステックとしては大きなチャレンジでした。
(アプリの立ち上げについては、Flutterを採用しています。詳しくはこちらをご覧ください。)
Hasuraは、先ほどもお伝えしたようにGraphQLエンジンです。開発の際には構築を支援してくれるツールでもあり、実際にリクエストの処理も行います。
「フレームワーク」ではなく、「エンジン」と呼称する所以です。
GraphQLエンジン...と言ってもなかなか難しいかもしれません。
デザイナーや、バックエンド開発を本業とされていない方々へ向けて、なるべく噛み砕いて説明すると、「フロントエンドのコードに欲しい情報を直接追加するだけで、バックエンドの改修なしにその情報が取れる」といったところでしょうか。
正確には上記は GraphQLの説明 で、Hasuraはこの機能を手数少なく実現できる、というものです。
もちろん、すべての改修が手数少なく実現できる訳ではありませんが、「データベースにあるこの情報も表示したくなった」程度なら本当にバックエンドの改修はゼロです。
例えば、Obremoでは、診断内容を元におすすめのペットフード情報を結果として表示しますが、「他の商品バリエーションを表示したい」といった改善を打つことが想定されます。
これまでのREST APIでは、このようにバックエンドから情報を返していました。
「他の商品バリエーションも表示する」という施策が始まると、まずは要求に合わせてバックエンドを改修。
バックエンドから情報が返ってくるようになります。
続いて、フロントエンドも改修をするという流れで、施策が完了していました。
一方、Hasura/GraphQLを採用すると、フロントエンドで欲しい情報を指定するだけでバックエンドから必要なデータが返ってくるようになります。
結果的に、より顧客体験に近いフロントエンドの改修に注力できる状態が実現します。
Hasuraでは、従来のGraphQLバックエンドの開発とは違い、単純なデータの読み書きであればデータ構造の定義さえあればコードを書かずともGraphQLエンドポイントを作成することができます。
また、在庫確保+決済処理などの複雑な実装(ビジネスロジック)は、Webhook等でHasuraの外に簡単に逃がすことができ、真に「ビジネスロジックに集中」することができます。
「データベースが変更されたことを検知してビジネスロジックを起動する」というちょっとしたイベント駆動を実現できる機能や、「毎日この時間に処理をする」というようなタスクスケジューリングの機能も備えています。
エンジニア向けにはなりますが、どれだけ簡単にGraphQLバックエンドを作れるかについては、以前記事を書いて触れましたのでご覧ください。
Rails × Hasuraの共存環境を作ってみる - Qiita
少し込み入った話をすると、RailsでGraphQLを採用することも安定択として視野に入れていたのですが、データベースの中身をそのまま取得するだけでもResolver等のコードを書く必要があるなど、実装の面倒さが目立ったためHasuraを採用しています。
Hasuraの導入が技術選定としては大きな決断だったのですが、「改善をなるべく早くする」という技術コンセプトとしては、もう一つヘッドレスCMSのStrapiの採用も重要なポイントです。
Strapiは、従来のCMS(ex: WordPress)とは違って「コンテンツの表示機能はなく、入稿できる機能だけ提供されているCMS」のようなイメージです。
Strapiの採用によって、現在はエンジニアがCMSを触ることなくマーケやデザイナーだけでコンテンツの入稿や管理を行うことができています。
本番環境では初のHasuraとStrapi採用でしたが、総じて採用してよかったと感じています。
Hasura
- イベント駆動のシステムを構築しやすく、まとめて決済処理をする場合でも「1つのイベントが失敗しても、失敗するのはその一件のみ」など、爆風を最小限にできた
- 逆に、40件の決済を1回の実行で捌こうとすると以下のようなデメリットが発生します。
- 実装自体が大規模になる
- 並列での処理や、ステータス管理まで含むと尚更
- 途中で処理の失敗が発生すると、そこで中断してしまうリスクが高まる
- どこまで実行が成功したのかの判断もつきにくくなる
- テーブル設計と基本実装を2人で賄えた
- 基本的なCRUDはデフォルトで提供されるので、テーブルさえ作ればバックエンドの実装を待たずにフロントエンド実装を始められる
- 定期的なタスク実行もCron Triggersとして機能に内包しているので、定期実行のためにインフラを用意する必要がない
Strapi
- 日本語UIが提供されているため、非エンジニアにそのまま渡しやすい
- リリース後のコンテンツ改善を非エンジニアメンバーのみで対応できている
- カスタマイズが容易で、プラグインも多く公開されているので、高機能なヘッドレスCMSをコスト低く構築できる
全体として
- HasuraやStrapiなど、一気に新しい技術を盛り込みすぎてしまったかもしれない(扱える人が少ないため、キャッチアップの手間が増える)
Hasura
- DBへのマイグレーションの管理は少し扱いづらく、Hasura以外にマイグレーションを任せた方がよかったんじゃないかと思っている(ActiveRecord / TypeORM等)
- 反面、Hasuraのマイグレーションは生のSQLなので、ポータビリティはかなりある
- 現状本番運用に耐える機能を実現するにはPostgreSQLを選定しなければいけない(選択肢が狭まる)
- 「既存事業も移行したい」等がそう簡単にはできない
- 実際、コマーステックのもう一つの事業であるcymaはMySQLであるため、横展開を断念している
Strapi
- 画像の管理機能があるが、2022/5現在フォルダ管理ができない (今後リリースされる予定)
- ロールベースの権限管理があるが、OSS版では作れるロールの数に制限があるので厳重な管理はできない
- ステージング環境・本番環境の用意はできるものの、環境間の同期に関して機能的なサポートはない(一部プラグインは存在する)
まとめると、
- 少ないエンジニアでの立ち上げをしたい
- 高頻度でLPOを行いたい
- ブラウザだけでなく、アプリからもアクセスを受け付けたい
という場面で、GraphQLおよびHasura、 Strapiは有効です。
「少ないエンジニアでの...」と書きましたが、「人数が多いとダメ」ではなく「少なくてもスムーズに開発できる」といったニュアンスです。
特にStrapiによるコンテンツ管理とVercelのDeploy hooksによるページビルドは、ローンチ後凄まじい効果を発揮しました。
エンジニアの知らぬ間にTOPページのデザインが変わっていることもありました。
また、新しい技術を採用したために発生した学習コストの高さには苦労をしましたが、乗り越えるための勘所は、以下にあると思います。
- 立ち上げメンバーが「自分以外が開発する」ことに対するプライドを捨て、早期に他メンバーに施策を任せる (前半は当てはまる場合のみ、後半が目的です。自戒を大いに込めています)
- そのために、リスク・難易度が低いタスクを捻出・列挙する
- 勉強会やレクチャー会を積極的に行い、他メンバーのエントリーのハードルを下げる
- 「勉強会なんてやってる時間ない!」の場合、まずはその問題を解消する
- 「開発スピードを伸ばすためには必要なことです」という合意を形成する
バックエンドやインフラの業務割合が多いと、「施策のための、改修のための改修」のような、直接的な顧客への価値提供につながりにくく、しかも人の手でやる必要がないような部分も少なからずあります。
Hasuraの採用は、「Obremoに関わるメンバーが、顧客への価値提供が最大化できる状態にする」という意図もあってのチャレンジでした。
今後、機会があれば、細かなHasuraのテクニックや、その奥のビジネスロジックにサーバレスアーキテクチャを採用したことについてもまた発信できたらと思います。
最後までお読みいただきありがとうございました。
立ち上げに関してはデザイナーの章さん、マーケターの加藤さんも記事を書いているのでよろしければご一読ください。
また、エイチームコマーステックでは現在フロントエンドエンジニアを募集しています!
カジュアル面談を受け付けていますので、僕たちの事業に興味がある方はぜひお話しましょう!