LoginSignup
43
17

More than 1 year has passed since last update.

引越し業界初の新サービスを支えるフロントエンドの技術

Last updated at Posted at 2021-12-02

この記事はエイチーム引越し侍 / エイチームコネクトの社員による、Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021 2日目の記事です。

「引越し侍 ネット見積もりサービス」

のβ版をリリースしました :tada:

昨日、 @sho-hata
「引越し業界初の新サービスを支えるバックエンド技術」というのを投稿してくれたので、
であれば、フロントエンドも、、ということで @anneauがフロントについてお話させていただきます。

結構、チャレンジングな技術構成してるので、皆さんの参考になる部分もあるかと思い、
イケてるところとイケてないと思ってるところを書こうと思います。

技術構成

まず、全体の技術構成は図を見ていただければと思います。

structure.png

画像作成: @sho-hata

フロントエンドに関係のある部分のみ解説します

Next.js

フロントエンドの構築にはNext.jsを採用しました。
Next.jsの詳細は不要かと思いますので、内部構成のみお伝えします。

  • SSRで実行
  • データの取得はGraphQL
  • ユーザー認証にはFirebase Authentication
  • リアルタイム性が問われるチャットにはFirestore

Hasura

あまり聞き慣れないかと思いますが、HasuraはGraphQL エンジンという役割を担っております。

スクリーンショット 2021-11-30 18.34.26.png

図のように、クライアントでGraphQLのクエリを定義し、Hasuraにリクエストを飛ばせば、自動的にSQLを作成し、データベースにクエリを走らせてくれます。

Firebase

ユーザー認証やチャットなどリアルタイム性が問われるところには、Firebaseを用いています。
Hasuraとも相性がよく、jwtでFirebase側のユーザー認証情報をHasura側で解釈することができます

イケてるところ

Next.js 採用による色々

普段開発してるとその恩恵が当たり前になりがちですが、

  • DX向上
    • Fast Refresh
    • TypeScript Support
  • UX向上
    • Image Optimization
  • その他
    • SSR Support
    • API Routes

等々、Vercel teamの皆さん、本当にお世話になっています :bow:

Hasura採用によるバックエンド工数削減

Next.js → Hasuraの通信にはGraphQLを用いています。
GraphQLでは、クライアントが望むデータをクライアント側に定義していくようになります。

query {
  profile {
    id
    name
    avatar
  }
}

本来であれば、GraphQLサーバーの方で、このクエリを解釈し、SQLを発行する必要がありますが、
上で述べたとおり、これらは全てHasuraが担ってくれます。

スクリーンショット 2021-11-30 18.34.26.png

認証やパフォーマンスチューニングもHasuraがやってくれるため、基本的にバックエンドが不要となります。

GraphQLでは解決できないような複雑な処理は HasuraからRest APIを呼び出せるようになっています。 僕たちのサービスでは、暗号化を必要とする部分や複雑なビジネスロジックはGolangに任せています

React Relay × Hasura 採用による型の安全性

API側のスキーマとTypeScriptの型定義をあわせるのは労力のいることかと思いますが、
現状、ほぼ0工数で実現することができています。

GraphQLのクライアントには、React Relayを用いており、
Hasuraが出力してくれるGraphQLスキーマをRelay Compilerにかませることで、
バックエンドとフロントエンドの型に一貫性をもたせることができています。

Nx採用によるモノレポ化

Nxというのはフロントエンド特化のモノレポ管理ツールです。

モノレポとは? 複数のプロジェクトを一つのリポジトリで管理しようという概念で GoogleやFacebook、Uberなど多くの企業が採用しているアーキテクチャです。

  • リソースの共通化
    • linterやbuilderの共通化
    • コンポーネントや処理の共通化
  • ビルドスピード向上
    • 変更を加えていない部分はキャッシュすることでビルドスピードを上げる
  • 依存関係の見える化

などメリットが多くあります。

例) ユーザー、提携企業、社内を一つのリポジトリで管理

image.png

このように一つのリポジトリで構成することでリソースの共通化がしやすくなります。

イケてないと思ってるところ

GraphQLによるフロントエンドのコード肥大化

GraphQLはクライアントから自由にデータを取り出せるというメリットがある一方、
パース処理などをクライアント側でする必要があります。

例) TODOコンポーネント

const STATUS = {
  1: '未着手',
  2: '着手中',
  3: '完了',
};

const query = graphql`
  query todoQuery on Todo {
    title
    status
    deadline
  }
`

const Todo: VFC = () => {
  const data = useQuery(query);
  return (
    <>
      <p>{data.title}</p>
      <p>{STATUS[data.status]}</p>
      <p>{dayjs(data.deadline).format('YYYY-MM-DD')}</p>
    </>
  );
}

バックエンドを介していれば、

  • ステータスはバックエンド側で変換して、表示用に日本語をもらう
  • 日付はフォーマットされたものを返してもらう

ということができますが、現状、これらがフロントの責務となってしまっています。

Firebaseの処理をクライアントが担っていること

構成図を見てもらえればわかるかと思いますが、
現状、フロントから発生する通信がHasuraに一本化できておらず、Firebaseとも通信をしております
できる限り保守しやすい状態は保とうとしておりますが、フロントエンドが担っている責務が大きすぎるような気がしています。

structure.png

今後の展望

やりたいことは色々ありますが、まずはイケてないと思っているところで取り上げた、
「フロントエンドの肥大化」というところは解消していきたいと思っています。

世の中的にはBFFによる解決策が多いかと思いますが、
僕たちの場合、HasuraがBFFに近い動きをしてくれていますし、Nextjsのapi routesも一部使用しているため、少し冗長な気もしています。

引き続き議論は進めていきますが、少なくともFirebaseの処理はサーバーサイドに寄せていきたいと思っています。

明日

Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2021 2日目の記事は、いかがでしたでしょうか。
明日は @ex_SOUL の投稿になります!お楽しみに!

43
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
17