Fusic Tech Blog

Fusion of Society, IT and Culture

【はじめての Raspberry Pi4】第 3 回 API Gateway でデータを取得!
2021/12/08

【はじめての Raspberry Pi4】第 3 回 API Gateway でデータを取得!

こんにちは、IoT チームの岡部ゆかです。

前回からの続きです。DynamoDB に環境センサーのデータが貯まっています。
今回はセンサーデータを API で取得したいと思います。

ざっくり方法

  1. Raspberry Pi の準備
  2. Raspberry Pi -> DynamoDB に IoT Core 経由でデータを貯める
  3. API Gateway で貯まったデータを取得する API を作る <- ここから

API Gateway と Lambda を用意する

世の中に溢れている記事を参考に API Gateway と Lambda 関数を作成します。
こちらを参考に
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-dynamo-db.html

参考記事は Lambda と DynamoDB を使用した CRUD API の構築ですが、今回は GET だけ作成しました。

チュートリアルを見つつ、関数を作成します。
ポリシーテンプレートを「imple microservice permissions」に設定しますが、Lamdba 関数の中身をいじるとポリシーが足りず、エラーになる場合があります。(今回チュートリアルにはない Lambda の Scan と Query 等を試しましたが、Query のポリシーがついていませんでした)
IAM から直接必要なポリシーをアタッチします。

また、チュートリアルでは DynamoDB のプライマリーキーは「ID」となっていますが、前回作成した DynamoDB のプライマリーキーは「device_id」なので修正する必要があります。

const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event, context) => {
  console.log("Received event:", JSON.stringify(event, null, 2));

  let body;
  let statusCode = "200";
  const headers = {
    "Content-Type": "application/json",
  };

  const tableName = "items";

  try {
    switch (event.routeKey) {
      case "GET /items/{id}":
        const params = {
          TableName: tableName,
          ExpressionAttributeNames: { "#hash": "device_id" },
          ExpressionAttributeValues: { ":hash": Number(event.pathParameters.id) },
          KeyConditionExpression: "#hash = :hash", //検索対象が満たすべき条件を指定
        };
        body = await dynamo.query(params).promise();
        break;
      case "GET /items":
        body = await dynamo.scan({ TableName: tableName }).promise();
        break;
      default:
        throw new Error(`Unsupported route: "${event.routeKey}"`);
    }
  } catch (err) {
    statusCode = "400";
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers,
  };
};

参考: AWS.DynamoDB.DocumentClient

参考: event-v2.json

APIGateway をデプロイして試してみます。
/items で全件取得、/items/1 でデバイス ID が 1 のものだけ取得。
JSON が返ってくれば成功です。(firefox 自動整形してくれてありがたーい!)
API をテストするために python の SENSOR_ID をちょいちょいと書き換えて擬似的に複数センサーを作りました。 環境センサーの値がズラッと取れています!

おわり

Raspberry Pi ・デバイスのセットアップから始まり、DB にためて、API でデータを取得するところまでできました。
はじめて Raspberry Pi と環境センサーを触り、デバイスが絡むシステムの一端に触れることができました。 分からないなりにチュートリアルを駆使して作成したわけですが、あまりいい出来とは言えません。
Raspberry Pi に証明書おいたけど、複数あるとき面倒だな
DynamoDB の設計はもっと API で取りやすいを考慮すべきだったな(timestamp がプライマリキーなのは辛く、DynamoDB 作り直した..)
セキュリティー関係(ポリシーも)あまり考慮しなかったな
などなど作っている途中にどんどん湧き出てきました。また作り直す時間もかかりました。
今回つらつらでスタートラインには立てたので次回はもう少しいい感じにできるはず!

さいごに、VS Code 拡張の Remote-SSH は超便利です!入れて損はない!

yukabeoka

yukabeoka

カスタマーサポートからエンジニアにジョブチェンジ。脳の老化に抗いがんばる。最近はAzureにいじめられている。