【ITニュース解説】Cloud Resume Challenge - Chunk 2 - Building the API
2025年09月19日に「Dev.to」が公開したITニュース「Cloud Resume Challenge - Chunk 2 - Building the API」について初心者にもわかりやすく解説しています。
ITニュース概要
Cloud Resume Challengeで、AWS Lambda、API Gateway、DynamoDB、IAMを使い、ウェブサイトにサーバーレスな訪問者カウンターを構築した。IPアドレスをハッシュ化し、24時間以内のユニーク訪問者をカウントする。セキュリティと効率性を重視し、REST APIで実装した。
ITニュース解説
この解説では、ウェブサイトに訪問者数を記録・表示する「訪問者カウンター」のバックエンド(裏側の処理)を構築したプロジェクトについて説明する。具体的には、AWS(アマゾンウェブサービス)の様々な機能を組み合わせ、ウェブサイト訪問者の数を記録し表示するシステムを作り上げる過程を追う。この目標は、単に数字を表示するだけでなく、AWS Lambda、API Gateway、DynamoDB、IAMといったサービスを連携させて、実際に動作するサーバーレスなバックエンドを構築することにあった。
訪問者カウンターの核となるのは、以下のAWSサービス群である。 **DynamoDB(ダイナモディービー)**は、ウェブサイトの訪問者データを保存するためのデータベースである。これは一般的なデータベースとは異なり、サーバーの管理が不要な「NoSQLデータベース」という種類で、大量のデータを高速に処理できる特徴を持つ。ここでは、訪問者のIPアドレス(プライバシー保護のためハッシュ化される)や訪問回数、最終訪問日時などを記録する。
次に、**AWS Lambda(ラムダ)**は、サーバーを意識することなくコードを実行できる「サーバーレスコンピューティング」サービスである。ウェブサイトからデータが欲しい、あるいはデータを更新したいといった要求があった時にだけ、必要な処理を実行するプログラム(関数)を動かすことができる。このプロジェクトでは、DynamoDBから訪問者データを取得したり、新しい訪問を記録してデータベースを更新したりする役割を担う。
**API Gateway(エーピーアイゲートウェイ)**は、ウェブサイトとLambda関数の間に立つ「窓口」のようなものだ。ウェブサイトからのリクエスト(「訪問者数を教えて」という要求など)を安全に受け取り、それをLambda関数に伝え、Lambda関数が処理した結果をウェブサイトに返す役割を果たす。これにより、ウェブサイトはLambda関数の詳細を知る必要なく、この窓口とやり取りするだけで必要な情報を得られるようになる。ここでは「REST API」という一般的な通信方式が採用された。
最後に、**IAM Roles(アイアムロール)**は、AWSのサービスやユーザーが、どのリソース(DynamoDBのテーブルなど)に対して、どのような操作(データの読み書きなど)を許可されるかを細かく設定するためのセキュリティ機能である。例えば、Lambda関数がDynamoDBのテーブルにアクセスしてデータを更新できるように許可を与え、それ以外の不必要な操作は禁止するといった設定を行う。これにより、システム全体の安全性が高まる。
これらのサービスは以下のように連携して動作する。 ウェブサイトのページが読み込まれると、ブラウザはAPI Gatewayに対して「訪問者カウンターの情報をちょうだい」というリクエストを送る。API Gatewayはそのリクエストを受け取ると、あらかじめ設定されているLambda関数を呼び出す。呼び出されたLambda関数は、DynamoDBにアクセスして現在の訪問者データを読み取り、必要に応じて新しい訪問情報を追加したり、既存の訪問情報を更新したりする。そして、Lambda関数はDynamoDBから得られた最新の訪問者数をAPI Gatewayに返し、API Gatewayはその情報をブラウザに送り、最終的にウェブサイトのフッター部分などに訪問者数が表示される仕組みだ。もし何らかの理由でデータが取得できなかった場合でも、「Loading...」と表示されるようにしておくことで、ユーザー体験を損なわない工夫がされている。
当初、このカウンターは単にページがリフレッシュされるたびに数を1つ増やす「ヒットカウンター」として設計された。しかし、より正確な訪問者数を把握するため、「ユニーク訪問者カウンター」へと改良された。これは、同じ訪問者(同じIPアドレスからのアクセス)が24時間以内に複数回ページを訪れても、カウントするのは1回だけにするというものだ。 この改良を実現するために、いくつかの変更が必要となった。まず、DynamoDBには訪問者のIPアドレスをハッシュ化した形で保存する新しいテーブルが用意された。IPアドレスを直接保存するのではなく、ハッシュ化することで個人の特定を防ぎ、プライバシーに配慮している。次に、Lambda関数も、新しい訪問者を識別し、24時間以内の再訪であればカウントを増やさない、というロジックを持つように賢く作り直された。
改良されたLambda関数(Pythonで記述)は、以下のような重要な処理を実行する。 まず、ウェブサイトからのリクエストに含まれる訪問者のIPアドレスを安全に取得し、そのIPアドレスをSHA-256という手法でハッシュ化する。これにより、元のIPアドレスが外部から推測されにくくなる。 次に、ハッシュ化されたIPアドレスを使ってDynamoDBに記録があるかを確認する。もし記録があれば、前回の訪問から24時間以上が経過しているかどうかを判断する。24時間以上経っていれば、その訪問者は新しいユニーク訪問者としてカウントされ、DynamoDBの訪問回数を1つ増やし、最終訪問日時を更新する。もし記録がなければ、その訪問者は完全に新しい訪問者と見なされ、DynamoDBに新しい項目としてIPアドレス、訪問回数、初回訪問日時、最終訪問日時が記録される。 これらの処理の後、Lambda関数はDynamoDBに保存されている全ての訪問者データから、ユニーク訪問者数(異なるハッシュ化IPアドレスの数)と総訪問回数(全ての訪問者が記録した訪問回数の合計)を計算し、これらの情報をウェブサイトに返す。これにより、ウェブサイトにはリアルタイムに近い正確な訪問者数が表示される。
システムの安全性を保つために、IAMロールは非常に重要な役割を果たす。「最小権限の原則」という考え方に基づき、各サービスにはその役割を果たすために最低限必要な権限だけが与えられる。 このプロジェクトでは、Lambda関数に対して、DynamoDBの特定のテーブルに対して「データの取得(GetItem)」「データの追加(PutItem)」「データの更新(UpdateItem)」「全てのデータのスキャン(Scan)」という操作だけを許可する設定が施された。これにより、Lambda関数は必要以上の操作を行うことができなくなり、万が一、Lambda関数に不正なアクセスがあったとしても、被害を最小限に抑えることができる。また、API Gatewayも、Lambda関数を呼び出すための権限のみが与えられている。
ウェブサイトのフロントエンド(HTML、CSS、JavaScriptなどの静的ファイル)はS3バケットに保存されているが、その設定もさらに強固になった。「バージョン管理」を有効にすることで、ファイルの誤った上書きや削除があった場合でも、以前のバージョンに復元できるようになった。これにより、ウェブサイトの安定性が向上する。また、「ライフサイクルポリシー」を設定することで、一定期間が経過した古いバージョンのファイルを、より安価なストレージクラスに自動的に移動させるようにした。これは、コストを抑えながらもデータの可用性を確保するための賢い戦略だ。
訪問者カウンターの構築にあたり、リアルタイムで訪問者数を更新する「WebSockets(ウェブソケッツ)」を使った方法も検討された。しかし、最終的にはシンプルで一般的な「REST API」が採用された。その理由はいくつかある。 まず、WebSocketsを使用すると、システムが大規模になった場合にコストが高くなる可能性がある。また、設定や最適化がREST APIに比べて複雑になる傾向がある。そして最も重要なのは、この訪問者カウンターという用途において、REST APIでもWebSocketsでも、ユーザーが感じる体験にはほとんど差がないと判断されたことだ。ページの読み込み時に一度情報を取得できれば十分であり、リアルタイム性がそこまで求められないため、シンプルで信頼性が高く、コスト効果にも優れたREST APIが最適な選択肢となった。
このプロジェクトの第2段階を通して、多くの重要な学びが得られた。 API Gateway、Lambda、DynamoDBを連携させて、機能する訪問者カウンターを構築できたことは大きな成果だ。ヒットカウンターをユニーク訪問者カウンターにアップグレードする過程で、より高度なロジックとデータベース設計が必要になることを経験した。IAMによる最小権限の原則を実践し、セキュリティを考慮した設計の重要性を理解した。S3のバージョン管理やライフサイクルポリシーを活用することで、ウェブサイトの堅牢性とコスト効率を高める方法を学んだ。そして、技術選定において、単に最新の技術に飛びつくのではなく、用途やコスト、複雑さを考慮した上で、最も適切な技術を選ぶことの重要性を実感した。 この段階で、フロントエンドとバックエンドが連携し、サーバーレスな構成でウェブサイトが完全に機能する「フルスタック・サーバーレス」の形が実現できた。これは、システム全体が協調して動作する感覚を初めて味わう体験であり、今後のプロジェクトへの自信につながるものだ。
次の段階である第3段階では、CI/CDパイプライン(継続的インテグレーション・継続的デプロイメント)の導入が予定されている。これは、コードの変更が自動的にテストされ、本番環境にデプロイされる仕組みを構築することで、開発プロセスをさらに効率化し、より信頼性の高いシステムを構築することを目指すものだ。このステップを経て、プロジェクトはさらに高いレベルへと進化する。