テクノロジー

ベストプラクティスなシステムデザインの作り方 〜 LINEギフトとヤフーショッピング連携における課題とその解決策

こんにちは、ヤフーショッピングでエンジニアをやっている市丸です。
先日LINE、ヤフー両社のeコマースサービスにおける連携強化のために、LINEギフトとヤフーショッピングの商品を連携するというサービスをリリースしました。(プレスリリース
本記事ではその開発の中で得たシステムデザインの知見についてお話しいたします。
※以後、本プロジェクトを「LINEギフト連携PJ」と呼びます

本記事でお伝えしたいこと

ご存知の方もいらっしゃるかもしれませんが、ヤフーはAIテックカンパニーとして常に新しい技術チャレンジをしています。
新しいサービスの開発・リリースを早いサイクルで実行していますが、ヤフーのエンジニアがサービス開発をし、その開発の中で新たな技術にチャレンジできているのには、その技術力の土台にしっかりとしたシステムデザインのスキルがあるからだと私は思っています。

システムデザインにおいては「パーフェクトプラクティスではなくベストプラクティスを選択する」ことが重要で、サービス開発と技術チャレンジを両立させるためには、このスキルが必要不可欠であると私は考えています。

本記事ではLINEギフト連携PJを実行するにあたりどのようにベストプラクティスなシステムデザインを行ったか? を具体例とともにお伝えします。
※記事内で扱うシステム構成図は簡略化されたイメージで、実際のものとは異なる場合がありますのでご了承ください

パーフェクト = ベスト とは限らない

本題に入る前に「パーフェクトプラクティスではなくベストプラクティスを選択する」とはどういうことか? について軽く触れます。
パーフェクトプラクティスとは、今後予想されるすべてのことに対応できるようにデザインされた文字通り完璧なシステム という意味です。
そう聞くと、パーフェクトプラクティスを選択するべきでは? と感じられるかもしれませんが、パーフェクトは必ずしもベストであるとは限らないという点を意識しておく必要があります。
なぜならば、パーフェクトなものを作るためには開発コストがかかることが多いですし、必要以上に作り込むことで出来上がったものがオーバースペックになってしまう可能性もあります。

つまり、現状の開発リソース、システム状態、サービス要求など、さまざまな状況に鑑みながら現時点でベストな選択をすることが「パーフェクトプラクティスではなくベストプラクティスを選択する」ということなのです。

システムはサービスの成長とともにアップデートしていくべきものですので、最初に必要以上に作り込むよりはサービスの成長タイミングで段階的にシステムをアップデートする方が効率がよく、ベストプラクティスなシステムデザインを続けることが結果的に技術チャレンジをするための余白を作ることにつながるはずである、と私は考えています。

LINEギフトとは?

「LINE」のトークを通じて友だちとギフトを贈り合うことができるコミュニケーションサービスです。
住所を知らなくても直接会えなくても、LINE上で簡単にギフトを贈ることができるため、
ちょっとしたお礼を言いたい時や季節イベント、大切なライフイベントなどさまざまなシーンでご利用いただいています。
出典:プレスリリース

このプロジェクトにアサインされたのをきっかけにLINEギフトを使ってみたのですが、LINEギフトは同じECサイトであっても自分のためのお買い物がメインのヤフーショッピングとはまったく違うサービスであると感じました。
友達に贈り物をしたくても、住所を聞かなければならないヤフーショッピングの課題を見事解決しているサービスがLINEギフトであり、記念日だけでなく、感謝の気持ちをこめたちょっとした贈りものや、友達に薦めたい商品なども気軽に贈れるのはとても便利で、使っていて楽しいサービスだと思います。

LINEギフト連携PJは何を目指し、何を実現したのか?

ヤフーショッピングには現在約4億商品があり、国内ECの中でも最大級の品揃えです。もちろんその中にはギフトに適した商品もたくさんあります。
このヤフーショッピングの商品をLINEギフト上にも並べ、LINEの友だちに贈れるようにすることで、両サービスのユーザーに新たな価値が提供できると考えました。システム上では、ヤフーショッピングの商品とその在庫データをLINEギフトのシステムの商品データベースにも連携する仕組みを開発しました。

PJのアウトライン

上図で表現すると非常にシンプルですが、実現にあたりさまざまな課題がありましたので、その課題とその中で選択したベストプラクティスについてご紹介していきます。

LINEギフト連携PJにおけるベストプラクティス

1、思い込みではなく、必要な仕様を見極めること

最初にご紹介するのは、在庫数の連携でぶつかった壁とそのブレイクスルーの話です。
ヤフーショッピングの商品の在庫数の変動は非常に頻度が高く、かつLINEギフト連携が始まるとさらにその頻度はあがります。
ヤフーショッピングで商品が購入されれば在庫はその分減りますし、ストアが在庫を補充すれば増えます。当然LINEギフトで商品が購入された場合もヤフーショッピングの在庫を減らさなくてはいけません。
これらをリアルタイムで、かつ不整合なく双方で同期をとる仕組みをつくるのは非常に開発コストがかかることがわかりました。

在庫連携のイメージ

この在庫数の連携についての課題解決にあたり、まずは商品と在庫ドメインモデルの関係について考えてみます。

皆さん、商品と在庫というとこのようなドメインモデルを想像するのではないでしょうか?

想定されるパーフェクトプラクティス
在庫ドメインのパーフェクトプラクティス

商品は在庫オブジェクトを持ち、在庫オブジェクトには「数量」が存在し、在庫数の確認ができたり、その商品の在庫数を増やしたり減らしたりできるドメインモデルです。
ヤフーショッピングにおいてもこれに近いドメインモデルで考えられております。
ですが、先にも述べた通りで、このドメインモデルのままLINEギフトPJを進めていくのは非常に開発コストも運用コストも高いことがわかっており、このまま進めることはできません。

解決の糸口を見つけるため、われわれはLINEギフトの仕様を正しく理解することに努め、1つの仕様に着目しました。

「LINEギフトでは商品は常に数量1で購入される」(執筆時現在)

最初はあまり気にしていなかった仕様でしたが、改めて見直すと数量を指定して購入できるヤフーショッピングとは実は大きく違う仕様であると気づきました。
つまり、LINEギフトにおいてはヤフーショッピングの商品の在庫の数量は重要ではなく、「ある or ない」 がわかれば成立するということです。
そして、ヤフーショッピング側のデータも確認したところ、在庫の数量の細かい変動はあっても、「在庫あり → なし」に変わる確率は低いというファクトがわかりました。

仕様の確認、データに基づくファクトの確認、この2つを経て導きだしたベストプラクティスはこうなりました。

導き出したベストプラクティス
在庫ドメインのベストプラクティス

ポイントをまとめると以下の2点です。

  • 在庫は数量ではなく「在庫がある or ない」の2パターンだけでよい
  • あり→なし に変わる確率は低いので在庫データの連携頻度を抑えられる

この結果、開発にかかるコスト、リリース後の運用にかかるコストを大幅に削減することに成功しました。

一般的には、「在庫」と聞くとそこには「数量」という概念が存在し、任意の数量を加算/減算できるモデルを設計しがちですが、
「本当にその仕様が必要なのか?」
を立ち止まって考えたことで非常にシンプルなものになりました。

今までの経験則から必要な機能を思い込みで実装してしまうことは多々あると思います。
処理を追加するのは簡単ですが、削除するのは労力と勇気が必要ですので仕様と向き合い、必要以上の処理を実装しないようにすることがベストプラクティスへの第一歩ではないかと思います。

あとからアサインされたエンジニアが「この処理は使われていない!」って証明するの難しいですよね。

2、データの鮮度の重要度を見極める

次は、商品データの鮮度についてのお話です。
商品データには、商品名、画像、価格といったストア運営者によっていつでも変更できるデータがたくさんあります。
ヤフーショッピングの商品は4億商品以上あり、商品データのエクスポートだけでも相当な時間がかかるため、リアルタイムでLINEギフトの商品データベースへ同期していくことは物理的に困難でした。
※商品データの更新をリアルタイムでヤフーが外部サービスに向けにパブリッシュし、クライアントがサブスクライブして自由に取り込む というアーキテクチャは検討は進んでいますが、まだ実現段階にはいたっておりませんでした。

参考 将来像のイメージ商品連携の将来像のイメージ

そのため、商品データの同期はデイリーで行う という選択肢を取りました。

ただその場合、ヤフーショッピングの商品の価格を変更しても、LINEギフト上の商品価格が更新されるのは翌日になってしまうことになります。
そして、その間はLINEギフト上では変更前の価格で商品が購入されてしまうということが起きてしまいます。
この問題の回避策として、

  • 商品の検索系処理においてはデイリーで連携しているLINEギフト側のデータソースを使って行う
  • ページに表示するヤフーショッピングの商品の情報は、ヤフーショッピングのAPIを利用してリアルタイムな情報を表示する

というアーキテクチャをとりました。

LINEギフト上においてユーザーと商品データのタッチポイントは大きくわけると

  1. TOPページ
  2. 検索結果ページ
  3. 商品詳細ページ
  4. 購入手続きページ

ですので、想定されるパーフェクトプラクティスはこのようになります。

想定されるパーフェクトプラクティス
API連携のパーフェクトプラクティス

ただ、このアーキテクチャを実現するにあたりわれわれにはどうしても避けて通れない問題があります。
それが「負荷対策」です。

こちらの記事にもあるように、ヤフーショッピングは超PayPay祭などの大型セールがあるとものすごい負荷がヤフーショッピングのシステム全体にかかります。
LINEギフトからAPI経由でリアルタイム参照しようとしている商品データベースはその高負荷を最も受けるデータベースであり、このアーキテクチャでは全ページが商品データベースをリアルタイムで参照しているため、ヤフーショッピング側の商品データベースが高負荷になったときにLINEギフトにまでサービス影響が出てしまいます。

それは避けなくてはなりません、そのためには商品データベースの手前にキャッシュ層を置き、ヤフーショッピングの商品データベースへの負荷、障害時の依存度を少しでも減らす必要がありました。

この課題を解決するために行ったのが「データの鮮度の重要度の見極め」です。
今回でいうと、リアルタイム性が必要な場所とそうでない場所はどこか? という見極めです。

上述した1〜4のページ遷移においてアクセス数と重要度の関係を整理するとこのようになります。

1.TOP 2.検索結果 3.商品詳細 4.購入手続き
アクセス数
データの鮮度の重要性

アクセス数は購入に近くなればなるほど少なくなります。
逆に購入に近ければ近い場所ほど、データの鮮度の重要度は上がります。
このようにまとめることで、アクセス数とデータの鮮度の重要性は反比例の関係にあることがわかり、以下の整理ができました。

  • TOP/検索結果はデイリーで連携した商品データを参照
  • 商品詳細は、キャッシュを間に挟んだAPIで参照する
  • 購入手続きはリアルタイムAPIを参照する

この整理により、LINEギフトから商品データベースをリアルタイムで参照する線は格段に減り、ヤフーショッピングの商品データベースへの負荷や障害時の依存度の課題はほぼ解決できました。

このアーキテクチャに関しては、常に負荷と戦っているわれわれのナレッジを活かし、先んじて対策を打てた という点です。

導き出したベストプラクティス
API連携のベストプラクティス

当然、常に最新の商品データで表示できるパーフェクトプラクティスの方がUX的には優れていますが、サービス全体が止まるリスクに鑑みると、現時点ではキャッシュ層を挟んだアーキテクチャがベストプラクティスであると判断しました。

すべてをリアルタイムの参照処理で実現するには設備投資も含め、コストが掛かることが多いです。
理想はすべてをリアルタイム化することであったとしても、改めて情報を可視化することでリアルタイム化しなくても成立しうる場所が見えてくると思いますので一度情報を整理して俯瞰してみるクセをつけると良いと思います。
可能であればログや実績データを分析し、ファクトベースで判断するようにしましょう。

もちろんこれはあくまで「現時点」でのベストプラクティスですので、こちらは前述したリアルタイム商品データ同期の構想を視野にいれて引き続きアップデートしていきます。

3、重要プロジェクトをきっかけにドメインを育てる

最後はこれまでとは少し違うパターンでサービスの成長とともにベストプラクティスをアップデートしたという話を「在庫引当」のビジネスロジックの課題を例にとってご紹介します。

在庫引当というのは、注文された商品の在庫を確保することで、システム的には「確保する分の在庫の数量を在庫データベースから減らしておく」という処理のことです。

在庫引当はこれまではヤフーショッピングで注文された場合のみしか実行されていませんでしたが、LINEギフトのシステムからも実行されるようになる、というのが今回新しく生まれた概念です。

ヤフーショッピングでは注文ドメインと在庫ドメインは別々に存在しているので、これを実現するためのアーキテクチャは皆さんもすぐに想像がつくと思います。

想定されるパーフェクトプラクティス
注文ドメインのパーフェクトプラクティス

まさにこのアーキテクチャがパーフェクトであり、ベストプラクティスですので、LINEギフトのシステムとヤフーショッピングの在庫ドメインをつなぐだけで本件は完了!

・・と言いたいところですが、実際のヤフーショッピングの在庫引当のビジネスロジックはもう少し複雑です。

というのも、ヤフーショッピングはモール型のECサイトですので、ストアがそれぞれ商品や在庫を管理しています。
また、ストアの中にはヤフーショッピングが提供する在庫管理システムではなく、自社で持っているシステムで管理していたり、3rdパーティーの運用ツールで管理しているケースもあります。

ヤフーショッピングもこのような外部のストア運用システムと連携するインターフェースは用意しており、その振り分けのビジネスロジックは「注文ドメイン」に存在していました。

そのため、実際はこのように、LINEギフトから注文ドメインを経由して在庫引当を行う必要がでてきます。

数年前のベストプラクティス
注文ドメインの数年前のベストプラクティス

注文ドメインが在庫引当先の振り分けのビジネスロジックをもつという設計は数年前においてはベストプラクティスであったと思います。
なぜならば在庫引当は注文時にのみ発生する処理であったため、無理にビジネスロジックを注文ドメインの外に持っていく必要がなかったからです。

しかし、この数年でヤフーショッピングは大きく成長を遂げ、その中核となる注文ドメインはさまざまな注文方法に対応する必要があり、肥大化した複雑なドメインになっていました。
そのため、現在においては注文ドメインはもっと注文の本質のビジネスロジックだけに集中し、在庫引当先の振り分けのビジネスロジックにおいては在庫ドメインに任せたいと考えていました。

ですが、日々スピード感を持って開発を行わなければいけなかったため、ドメインの責務を整理してシステムをアップデートすることに開発コストを割くタイミングを逃していました。

このように1つのドメインが本来持つべきでないビジネスロジックを持つことで肥大化し、触るのが怖いシステムになっていった という経験は皆さんもあるのではないでしょうか?
また、ドメインを整理したい と思ってもなかなか専用の時間がとれないことも多いと思います。
エンジニアあるあるですね。

LINEギフト連携PJはZホールディングスからみても重要な位置づけでした。重要なプロジェクトであればあるほど失敗を恐れて変更箇所を少なくした消極的な開発になりがちだと思います。
今回、もし在庫引当において消極的な開発をしていたら上図のように本来経由する必要がない注文ドメインを経由して在庫引当を行うビジネスロジックが注文ドメインに生まれることになったと思います。

いわゆるシステムの新たな闇の誕生です

われわれはその選択肢は取らず、あえてこのタイミングで積極的にドメインの責務を見直す選択肢をとりました。
重要なプロジェクトや大きなプロジェクトは得てして新しい概念が生まれるケースが多いと思います。
今回においては、「外部のシステムからヤフーショッピングの商品の在庫引当を行う」という概念がまさにそうでした。

新しい概念が生まれるときこそ、ドメインを育てるチャンスです。

LINEギフト連携PJをすすめる中で、これまで手をつけられなかった注文ドメインと在庫ドメインの責務の整理を行い、現在の状況にフィットした形にドメインを育てられました。

その結果、最初にあげたベストプラクティスのアーキテクチャを実現できただけでなく、ドメインの整理ができたことで今後の開発の効率化にもつなげることに成功しました。

現在のベストプラクティス
注文ドメインのベストプラクティス

冒頭で述べたとおり、ベストプラクティスの選択はサービス成長に合わせてシステムをアップデートしていくということです。
そのタイミングをいつとするか? というのは意外と見落とされがちだと思いますが、このように大きなプロジェクトが立ち上がったときは得てしてサービスが成長するタイミングでもあるので、「ドメインを育てるチャンスだ」とポジティブに考え、あえて積極的な開発をするのが良いと思います。

きっと重要プロジェクトを成功させただけでなく、今後の開発にも貢献した! という1度で2度おいしい体験ができると思います。

まとめ

本記事で私がお伝えしたかったシステムデザインについて最後にまとめます。

  • システムデザインをする上で大事なことは完璧なものにこだわることではなく、その時のベストプラクティスを選択することである
  • ベストプラクティスへの近道は、思い込みは捨て、サービスとして必要な仕様としっかりと向き合うことである
  • ベストプラクティスはサービスの成長とともに変わり、サービスの成長タイミングで見直していくものだから、今完璧なものを作る必要はない
  • 重要プロジェクトこそドメインを育てるチャンス! 恐れずシステムをアップデートするべし

個人的な意見でもありますが、先を見越して今存在しない仕様の開発をしてしまうより、その時が来たときに簡単に手がいれられるようにドメインを育てておくことが重要だと思っています。

本日ご紹介したようなシステムデザインスキルを磨くことで適切な投資で開発ができるようになり、できた余白を技術チャレンジに割けますし、サービス開発の中で技術チャレンジをするようなシステムデザインの仕方もできるようになると思います。

システムデザインにゴールはなく、常にアップデートし続ける必要がある というのが終わりのないゲームをやっているような感覚で非常に面白いですよね。

最後に

LINEギフト連携PJを通じてLINEのエンジニアの方ともたくさん会話することができました。LINEのエンジニアの皆さんは非常に技術力が高く、とても刺激的で楽しい時間を過ごせました。
もちろん、今回のシステムデザインもヤフーだけで行ったのではなくLINEとヤフーのエンジニアがたくさん議論を行って生み出したものです。

LINEギフト連携PJはまだまだ始まったばかりで、これからさらなる成長のための開発が既に決まっており、現在その実現にむけたシステムデザインを絶賛行っているところです。
今はまだ多くは語れませんが、再びドメインを育てるチャンスに直面しており、大変ワクワクしております。

さて、ここまでだいぶ偉そうに記事を書きましたが、私もまだまだ未熟です。これからもヤフーショッピングのエンジニアとしてこういった技術情報の共有をし、フィードバックをいただきながら技術力を磨き、皆様によりよいサービスを提供していけるように日々エンジニアライフを楽しんでいければと思っております。

この記事が、少しでも皆様の参考になりましたら幸いです。
最後まで読んでいただきありがとうございました。


市丸 数明
ヤフーショッピング エンジニア
ヤフーショッピングのCRMシステムなどデジタルマーケティングのシステムの開発の責任者をしています。

関連記事

このページの先頭へ