[AWS Lambda] APIから取得したCSV形式のデータをJSON形式に変換する(AWS CDK)

2021.11.17

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、APIから取得したCSV形式のデータをJSON形式に変換するAWS Lambda関数をAWS CDKで作成してみました。

やってみる

準備

準備として下記の内容のCSVファイルusers.csvをS3バケットにアップロードします。(この用途については後述します。)

userId,userName,age
u001,Tobey,46
u002,Kirsten,39
u003,James,43
u004,Alfred,68
u005,Rosemary,94

csvtojsonの導入

今回、CSV形式のデータをJSON形式に変換するために用いたのはcsvtojsonです。。CSV文字列からの変換とCSVファイルからの変換のいずれにも対応しているライブラリです。

csvtojsonをインストールします。

$ npm install csvtojson

CDKコード

src/lambda/handlers/sampleHandlers.ts

import * as cdk from '@aws-cdk/core';
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs';
import * as iam from '@aws-cdk/aws-iam';

export class AwsCdkAppStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const getCsvData = new lambdaNodejs.NodejsFunction(this, 'getCsvData', {
      functionName: 'getCsvData',
      entry: './src/lambda/handlers/sampleHandlers.ts',
      handler: 'handler',
    });

    getCsvData.addToRolePolicy(
      new iam.PolicyStatement({
        actions: ['s3:GetBucketLocation', 's3:GetObject'],
        resources: [
          'arn:aws:s3:::wakatsuki-bucket',
          'arn:aws:s3:::wakatsuki-bucket/*',
        ],
      })
    );
  }
}

Lambdaコード

Lambda関数のハンドラーのコードです。実際にはAPIからAxiosでCSVデータを取得したのですが、クローズドAPIのためブログ内で詳しい仕様の記載はできなかったので、代わりにS3バケットにCSVファイルをアップロードしてそれをAWS SDKで取得するメソッドを実装しています。

import * as AWS from 'aws-sdk';
import csvtojson = require('csvtojson');

const s3 = new AWS.S3();

export const handler = async () => {
  const csvData = await getCsvApi();

  return await csvtojson().fromString(csvData);
};

//ブログ用にS3で実装
const getCsvApi = async () => {
  const data: any = await s3
    .getObject({
      Bucket: 'wakatsuki-bucket',
      Key: 'users.csv',
    })
    .promise();
  return data.Body.toString('utf-8');
};

//実際に使用した実装
/*
import Axios from 'axios';

const getCsvApi = async () => {
  const response = await Axios.get('https://api.example.com/users', {
    headers: {
      'x-apiKey': 'api-key',
    },
  });
  return response.data;
};
*/

cdk deployでLambda関数をデプロイします。

動作

作成したLambda関数を実行します。

するとJSON形式に変換されたデータを取得できました。

[
  {
    "userId": "u001",
    "userName": "Tobey",
    "age": "46"
  },
  {
    "userId": "u002",
    "userName": "Kirsten",
    "age": "39"
  },
  {
    "userId": "u003",
    "userName": "James",
    "age": "43"
  },
  {
    "userId": "u004",
    "userName": "Alfred",
    "age": "68"
  },
  {
    "userId": "u005",
    "userName": "Rosemary",
    "age": "94"
  }
]

類似のライブラリ

CSVのJSONへの変換に利用できるnpmライブラリには、メジャーなものでcsvtojsonconvert-csv-to-jsonがあります。下記は現時点(2021/11)の両ライブラリの比較です。

csvtojson convert-csv-to-json
Last publish 2年前 5ヶ月前
Weekly Downloads 465,944 12,093
JSON文字列からの直接変換 可能 できない?
Unpacked Size 8.69 MB 82.7 kB

convert-csv-to-jsonの方がアクティブにメンテナンスが行われていますが、JSON文字列からの直接変換はできません。(行いたい場合はファイルに格納する処理を自前で実装する必要がありそう。)しかしそのためかパッケージサイズはcsvtojsonの1/100近くととても小さくなっています。やりたいことに応じて使い分けをすると良さそうです。

以上