logo

Next.js + S3 Clientのローカル環境構築手順とオブジェクト取得まで(AWS SDK for JavaScript)

概要

本記事ではS3Clientを用いて、Next.js上でのAWS SDKのローカル環境構築の方法についてまとめます。
構築後はAPI Route経由でS3からオブジェクトを取得して動かしてみます。

※ AWSやNext.jsの基本的な使い方については省略しています。

環境

環境バージョン
Next.js16.0.0
@aws-sdk/client-s33.919.0

AWS

1. S3バケットを作成

以下の設定で作成を行います。

項目設定
オブジェクト所有者ACL無効
パブリックアクセスすべて無効
バージョニング無効
暗号化タイプAmazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3)
バケットキー有効
S3バケット作成画面

2. S3バケット操作用IAMアカウントを作成

AmazonS3ReadOnlyAccessポリシーが許可されたアカウントを作成。
今回はポリシーを直接アタッチするの項目からポリシーを設定しています。

IAMアカウント作成画面

3. 作成したIAMアカウントのアクセスキーを作成

Next.jsで使用するために、作成したIAMアカウントのアクセスキーを作成
ユースケースはAWSの外部で実行されるアプリケーションを選択

アクセスキー作成画面

Next.js

1. @aws-sdk/client-s3インストール

npm

npm install @aws-sdk/client-s3

yarn

yarn add @aws-sdk/client-s3

pnpm

pnpm add @aws-sdk/client-s3

2. 環境変数を設定

.env.localに以下の環境変数を設定
AWS > 3. 作成したIAMアカウントのアクセスキーを作成で取得した値をセットしてください。
AWS_REGIONはバケットを作成したリージョンを指定してください。

# AWS Credentials
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=

# S3 Configuration
AWS_S3_BUCKET_NAME=

3. S3バケットからファイルを取得する処理を実装

API Routesでバケットからファイルを取得し返却するAPIを実装

app/api/s3/object

import { NextRequest, NextResponse } from "next/server";
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";

export async function GET(request: NextRequest): Promise<NextResponse> {
  try {
    // S3Clientを生成(環境変数から自動的に認証情報を取得)
    const client = new S3Client();

    // クエリパラメータからファイル名を取得
    const searchParams = request.nextUrl.searchParams;
    const key = searchParams.get("key");

    if (!key) {
      return NextResponse.json(
        { error: "Key parameter is required" },
        { status: 400 }
      );
    }

    // S3からオブジェクトを取得
    const response = await client.send(
      new GetObjectCommand({
        Bucket: process.env.AWS_S3_BUCKET_NAME,
        Key: key,
      })
    );

    // レスポンスボディをバイナリで取得
    const bodyBytes = await response.Body?.transformToByteArray();

    if (!bodyBytes) {
      return NextResponse.json(
        { error: "Empty response body" },
        { status: 500 }
      );
    }

    // Content-Typeを取得
    const contentType = response.ContentType || "application/octet-stream";

    // バイナリデータをBase64エンコード
    const base64Content = Buffer.from(bodyBytes).toString("base64");

    return NextResponse.json({
      data: base64Content,
      contentType: contentType,
    });
  } catch (error) {
    console.error("S3 fetch error:", error);
    return NextResponse.json(
      { error: "Failed to fetch object from S3" },
      { status: 500 }
    );
  }
}

S3Clientを生成

プロバイダーチェーンにより環境変数からアクセスキーを自動で取得し、クライアントを生成することができます。

// S3Clientを生成
const client = new S3Client();

Set credentials in Node.js / Credential provider chain

docs.aws.amazon.com

GetObjectCommand()でオブジェクトをS3から取得

バケット名とキーを指定し、オブジェクトを取得

// S3からオブジェクトを取得
const response = await client.send(
  new GetObjectCommand({
    Bucket: process.env.AWS_S3_BUCKET_NAME,
    Key: key,
  })
);

取得したオブジェクトのバイナリデータを取得

// レスポンスボディをバイナリで取得
const bodyBytes = await response.Body?.transformToByteArray();

コンテントタイプを取得

Jsonに設定するためのコンテントタイプを取得
取得したコンテントタイプがundefinedだった場合はapplication/octet-streamを設定。

// Content-Typeを取得
const contentType = response.ContentType || "application/octet-stream";

オブジェクトをBase64エンコード

Jsonのテキストとして値を返すためにバイナリデータをBase64でエンコードを行う。

// バイナリデータをBase64エンコード
const base64Content = Buffer.from(bodyBytes).toString("base64");

値を返す

return NextResponse.json({
  data: base64Content,
  contentType: contentType,
});

4. 実装したAPIにアクセスする

ブラウザかCurlコマンドでhttp://localhost:3000/api/s3/object?key=[キー名]にアクセスして動作を確認

$ curl http://localhost:3001/api/s3/object?key=sample.txt
{"data":"SGVsbG8gV29ybGQ=","contentType":"text/plain"}