あかね
「参考になった」ボタンを、UI/UXからAPI・DBまで考えてみた
2026年08月23日
要約を生成中...
はじめに
ECサイトによくあるレビュー機能に「参考になった」ボタンをつけたい、という話が出ました。
というかfigmaにあって、レビュー機能作ってる時にこれいるんですか?みたいな感じで聞いたらいるってことで、何に使うのか聞いてみると、どうやら分析とかで使いたいらしい。
何の分析かまでは知らないし多分まだ考えてない。笑
まぁデータが取れてたらOKだからやることは別に目的に応じて変わるものでもないと解釈。
レビューごとに「参考になった」がどれくらい押されているか取れれば、何かしら使えるのはわかります。

このレビューごとにある「参考になった」ボタンです!
専門領域ではないなりにUIの挙動と実装仕様を詰めた話です。
仕様を詰めたい
今回まず気になったのは、ログインしていないユーザーが押した場合どうするのか?というところです。
聞いてみたところ、「Amazonってどうなってる?」とのこと。
なるほど。明確に「こういう仕様にしたい」があるわけではなく、Amazonを参考にしたいらしい。
それなら話は早い。Amazonを見に行くまでだw
まずは普通に押してみる
ログインした状態で、レビューの「参考になった」を押してみる。
すると、ボタンだったのが
フィードバックをお寄せいただきありがとうございます。
という表示に変わりました。ここまでは普通です。
気になったのでリロードしてみます。
リロードしてみる意図は、商品の詳細画面のレスポンスにログインユーザーが参考になったボタンを押したことがあるのか否かの情報を持たせないといけないのか否かの判断に必要だと思ったからです。
やってみると、また「参考になった」ボタンに戻りました。(内心ガッツポーズ!!商品詳細APIの変更がいらない!!w)
もう一度押せる。押すと、また同じメッセージに変わる。何回やっても同じでした。
さっきの話ですが、Amazonは少なくとも画面を表示するときに、「このユーザー、このレビューにもう投票してるよ」という情報を使ってボタンを出し分けてはいないらしい。
投票済みでも未投票でも、最初は同じ「参考になった」ボタンの表示しているだけです。
そして押したあとだけ表示が変わる。
つまり、この表示自体はクライアント側で持てばそれだけでよさそう。
投票状態を取得して初期表示に反映する必要はない。めちゃシンプル。楽や〜バンザイ
ログインしてない状態では?
次にログアウトして押してみます。
参考になったボタンを押すとログイン画面に飛びました。
なるほど。つまりAmazonの挙動をそのまま参考にするなら、
ログイン済み → 投票できる
未ログイン → ログイン画面へ
投票済みかどうかで初期表示は変えない
ここまでは決まったOK!楽勝!!
でも、まだひとつ気になる。同じ人が何回も押したら、どうなるんだろう???
リロードしたらボタンになるから気になるところです。
Networkを見てみる
ということでDevToolsを開いてNetworkを見る。
「参考になった」を押したタイミングでPOSTが飛んでます。

エンドポイントは https://www.amazon.co.jp/acp/cr-top-reviews/cr-top-reviews-9hogehoge/helpful?page-type=Detail&stamp=hogehoge となってます。
Payloadにはこんな情報が入っていた。
reviewId
asin
domain
returnToreviewId があるので、対象は明確にレビュー。
つまり、このレビューを helpful と評価するためのPOSTっぽいことが明らかです。
さらに、同じレビューで何回繰り返してもレスポンスは同じ。

{
"success": true
}すでに投票しているからエラーになるわけでもなく、2回目だから別のレスポンスになるわけでもなく、何度送ってもクライアントから見える結果は同じです。
なるほど。この挙動を再現するなら、冪等にすればいいわけねと解釈。
この挙動を自分たちで再現するなら、冪等なAPIとして設計できそうという話でAmazonが実際どうしてるかはわかりません。
DBもだいたい見える
大体DB設計も見えてきます。
今回やりたいのは「誰が、どのレビューを参考になったと思ったか」を保存することなので、かなりシンプルです。ログインユーザーに絞ってくれてるのでそこが救いですw
ここが違うと設計だいぶ変わる、、
登場人物は、
Customer
Review
この2つですね。
ということは、この間に「参考になった」という関係を持たせればいいだけです。
例えばこんなテーブル。
review_helpfuls
customer_id
review_id
created_at
updated_atそして、
UNIQUE(customer_id, review_id)を張ります。
同じCustomerが同じReviewに投票できるのは1回だけで、POSTされたときは、まだレコードがなければINSERT。
すでに存在していれば増やさず、そのまま成功を返すだけ。
これなら、何回ボタンを押しても successでも、投票数は増殖しないです。
Amazonで観察した挙動を再現できるなって思いました。
仕様がなくてもUXから観察する
最初にあった仕様は、「レビューに参考になったボタンがほしい」これだけです。
ログインしてない人どうする?投票済みだったらどうする?リロードしたらどうなる?同じ人が何回押したらどうなる?APIは何を送ってる?
このへんは特に何も決まっていませんでした。
でも、既存サービスを実際に触って、
UIの挙動を見る
ログイン・未ログインで比較する
リロードしてみる
同じ操作を何回か繰り返す
Networkを見る
Request / Responseを見る
と追っていくと、じゃあ自分たちで再現するならこうだなが見えてきます。
今回なら最終的には、CustomerとReviewの間にテーブルを作って、複合ユニークインデックスを張るまで落とし込めました。
おわりに
デザイナー不在なのでエンジニアがUX考えてるプロダクトですが、既存の真似でもいけるサービスであればフルスタックエンジニアほど強いものないなってちょっと思いましたw
こういうのほんとに楽しいです。
amazonのUXが複雑じゃなかったから助かったのもありますがw
画面だけ先に作って後から「DB設計的にこのデータ持てないじゃん…」みたいな無理が出る壁にぶつからず(まぁフェーズによるけど自分でデータモデル考えられるし)、フロントのUX体験とバックエンドのテーブル制約(複合ユニークなど)を最初から整合させて一気に進められるっていうのがいいですよね。
レイヤー跨いで見れるのはフルスタックエンジニアの本当に強いところであり、最高に面白い部分だなと改めて思いました✌🏼




