この記事は 弁護士ドットコム Advent Calendar 2022 の 5日目の記事です。

これはなに?

ブログや記事サイトで使える「いいねボタン」を簡易的に作ってみた内容の紹介です。

作ったもの

挙動

いいねボタンの下に現在のいいね数を表示しています。
ボタンはクリックするごとにいいねを登録・解除します。
いいねの状態に合わせていいね数が増減します。

特徴

  • WebAPIとして疎結合にしているので、好きな箇所に柔軟に配置できる
  • ボタン以外からいいねの増減をする際にもWebAPI部分をそのまま使える
  • ボタンをコンポーネント化しているので作り込んでも再利用しやすい
  • 作りが導入するサイトに依存していないので、いろんなサイトに使いまわしが効く
  • ContentfulのWebAPIを利用している分、複数に同時リクエストされるとトランザクションの前後が発生するが、中間のLambdaでエラー率を緩和している

構成

構成図

ざっくり以下の要素で構成しています。

  • データの永続化はContentful
  • フロントエンドはReact
  • Reactで作成したクライアントサイドのホスティングはVercel
  • いいね数の更新リクエストを受け付けるIFはAmazon API Gateway
  • いいね数の更新処理を行うのはAWS Lambda(ランタイムはGo)

データの永続化にContentfulを利用している理由

  • いいねボタンをページ上に表示したいケースは多くの場合ブログやなんらかの記事サイト
  • ContentfulはHeadlessCMSとして主流となっており、私のブログでも採用しているサービス
  • 小規模に運営しているサイトであるほど、システムの構成は複雑にしたくない
  • 新たに専用のストレージを導入せずに記事情報と同じ箇所(CMS)にいいね数をまとめられるようにした

その他の採用理由

  • フロントエンドのReactは私のブログに合わせている
  • Vercelはデプロイが容易で私の他のサービスでも多く利用している
  • Amazon API Gateway + AWS Lambdaはコストが安く構成としてもシンプルで作りやすい
  • Goは業務で書いている上、シンプルなコードとも相性がよく、高速に実行される

実装

領域ごとに実装を分けてリポジトリに公開しています。

それぞれのREADMEに使用方法やセットアップ手順をすべて記載しています。
とはいえリンク貼って終わりでは紹介記事の中身がすっかすかなので、かいつまんで解説いれます。

フロントエンド(いいねボタン)

作りとしてはCreate React Appした初期状態を少し改変して、いいねボタンを追加しているだけです。

いいねボタンは下記の機能となっています。

  • クリックすると「いいね」されて「いいね数」が増える
    • もう一度クリックすると「いいね」が解除されて「いいね数」が減る
  • いいねの状態はページをリロードしたりブラウザを再起動しても維持される
  • いいねするとキラキラアニメーションが発生する

いいねの状態維持にはクライアントサイド(ブラウザ)に保持されるlocalStorageを利用しています。
いいねした際のアニメーションにはLottieというライブラリを使用しています。

いいね数はサーバーサイド(Contentful)を正にはしていますが、どうしてもリクエストからレスポンスまでにタイムラグがあるため、クライアントサイドでもいいね数を管理して描画に反映しています。
利用者からすると瞬時に反映されているように見えますが、実際には非同期で少し後に反映されています。

いいね数の参照・更新を行うLambda関数

API GatewayでREST APIとして「いいね数の参照」「いいね数のインクリメント」「いいね数のデクリメント」のエンドポイントを用意しています。
APIがリクエストされた際は紐付けられたLambdaが実行されます。

Lambdaの関数はGoを使って実装しています。
共通処理のパッケージ化、テストコードの実装、ローカル環境でのCLI実行を対応しました。(本当はパッケージ部分を別のリポジトリにまとめたかったけど、時間切れなのでまた今度…)

おわり

やっつけで作った感はありますが、個人レベルなら困らない程度の実装になったと思います。
本ブログのいいねボタンの実装もこの内容で更新予定です。

明日の 弁護士ドットコム Advent Calendar 2022 の記事を担当するのは @oden7777 さんです!