フリーランス
エンジニア
AWS SDK for JavaScript v3のアップデート概要と、旧バージョンからの書き換え
フロントエンドエンジニアとしてフリーランスで活動している久米と申します。
IaaS型クラウドにおけるシェア1位のAWS。かくいう私も以前執筆した記事で紹介しているように、本サイト「エンジニアファースト」の実装でもAWSを用いています。また他の業務では、フロントエンドエンジニアと名乗っておきながら、API GatewayやAppSyncを用いたAPI実行時の処理などを中心に、バックエンド開発などさまざまな場面でAWSを活用しています。
昨年末(2020年12月)にAWSが提供する「AWS SDK for JavaScript」のバージョン3が公開され、ある程度実際の開発でも使用してみたので、今回はその概要やバージョン2からの書き換え方法などを紹介していきます。
AWS SDK for JavaScript v3の概要
まず最初にバージョンについての注意事項です。
本記事では「AWS SDK for JavaScript」のバージョン3についての記事となりますが、既存のAWS SDKをアップデートして使用するわけではありません。npmパッケージ自体が既存のものとは別のものになっています。
v2
$ yarn add -D aws-sdk
v3(本記事で扱うものはこちら)
$ yarn add -D @aws-sdk/client-s3
使用方法などは後ほどご紹介いたしますが、詳しくは下記の各種バージョンのGitHubリポジトリをご参照ください。
AWS SDK for JavaScript v2
AWS SDK for JavaScript v3
バージョン3から新たに追加された主な機能は下記になります。
・ 新しいミドルウェアスタック
・TypeScriptに対する充実したサポート
・必要なパッケージのみの分割インポート対応
引用元:AWS SDK for JavaScript バージョン 3 が一般公開を開始
具体的な内容をひとつずつ見ていきましょう。
新しいミドルウェアスタック
参考:Introducing Middleware Stack in Modular AWS SDK for JavaScript | Amazon Web Services
データの送信時などに動作するミドルウェアに、任意のアクションの追加などができるようになりました。
具体的な活用方法としては、通信が行われる際にカスタムヘッダーにメタデータを追加する方法などが紹介されています。
index.jsimport { S3Client } from '@aws-sdk/client-s3'
const client = new S3Client({
region: 'ap-northeast-1'
})
// 全てのコマンドの共通処理としてカスタムヘッダーを追加する
client.middlewareStack.add(
(next, context) => async (args) => {
args.request.headers['x-amz-meta-foo'] = 'bar'
const result = next(args)
return result
},
{
step: 'build',
name: 'addFooMetadataMiddleware',
tags: ['METADATA', 'FOO']
}
)
このような処理のように、SDKの動作をカスタマイズすることによって、リクエストのデバッグなどが容易になるとのことです。
TypeScriptに対する充実したサポート
参考:First-class TypeScript support in modular AWS SDK for JavaScript | Amazon Web Services
以前のバージョン2でも型定義自体は提供していましたが、それらは開発後に利用者の要望を元に追加で定義したものであり、SDK自体がTypeScriptによって記述されたものではありませんでした。そのため、型定義がコードの記述と正確に紐づけられたものではなく、型定義との齟齬(そご)が生じる可能性を捨て切れませんでした。
また、「技術遷移から見る現代のWebアプリケーションに求められるフロントエンド」の記事でも紹介したように、近年ではバックエンドでTypeScriptを採用するケースも増え、開発の現場ではよりいっそう、型定義の重要性が高まっています。
今回のバージョンから上記のような問題や、昨今のトレンド、各企業のTypeScript採用の流れを加味した上で、TypeScriptによる開発を行ったことで、SDKの品質向上を図ったとのことです。
下記のように各種IDEでより正確なコード補完が行われ、開発体験の向上にもつながっています。
例)Visual Studio Code
SDKの開発をTypeScriptで行ったことにより、APIドキュメントの正確性も担保されました。
ドキュメントの生成にはTypeDocを使用することでコードの変更を元に反映することが可能になっているとのことです。
必要なパッケージのみの分割インポート対応
参考:Modular packages in AWS SDK for JavaScript | AWS Developer Tools Blog
バージョン2では単一のAWSサービス、例えばS3のみを操作する場合でもAWS SDK全体をインストールする必要がありました。
バージョン3からは下記のように使用するAWSのサービスごとにインストールすることができ、プロジェクトファイルの軽量化に大きく貢献します。
v2
$ yarn add -D aws-sdk
# aws-sdk全体をインストールする
import { S3 } from 'aws-sdk'
v3
$ yarn add -D @aws-sdk/client-s3
# 使用するサービスごとにインストールする
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'
その他にも高レベルの操作を行う関数、ユーティリティ関数などの使用がより簡潔になっています。
前述のような各サービスのクライアントに加え、@aws-sdk/lib-〇〇
、@aws-sdk/util-〇〇
のようなプレフィックス付きのモジュールをそれぞれの機能ごとに使用することができ、必要な機能だけを扱うことで軽量化が図れます。
index.jsimport { DynamoDBClient, UpdateItemCommand } from '@aws-sdk/client-dynamodb'
import { marshall } from '@aws-sdk/util-dynamodb'
async function updateItem() {
const dynamoDBClient = new DynamoDBClient({
region: 'ap-northeast-1'
})
try {
await dynamoDBClient.send(
new UpdateItemCommand({
TableName: 'TestTable',
Key: marshall({
HashKey: 'hash'
})
})
)
} catch (error) {
throw new Error(error)
}
}
updateItem()
v2からの書き換え
本記事公開時点ではAWS SDKのバージョン3はリリースしてから日が浅いため、AWS SDKを使用したネット上で散見される多くの記述例では、バージョン2を用いた記述が多く見受けられます。
今回はそれらの知見を活用するためにも、バージョン3への書き換えを実際に行っていきます。
本記事ではS3からデータを取得する際の記述を例に見てみましょう。
v2
index.jsimport { S3 } from 'aws-sdk'
const s3Client = new S3({
region: 'ap-northeast-1',
credentials: {
accessKeyId: 'your-access-key-id',
secretAccessKey: 'your-secret-access-key'
}
})
async function getS3ObjectV2() {
try {
const response = await s3Client.getObject({
Bucket: 'bucket-name',
Key: 'test/app.json'
}).promise()
console.log(response)
} catch (error) {
throw new Error(error)
}
}
getS3ObjectV2()
v3
index.jsimport { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'
const s3Client = new S3Client({
region: 'ap-northeast-1',
credentials: {
accessKeyId: 'your-access-key-id',
secretAccessKey: 'your-secret-access-key'
}
})
async function getS3ObjectV3() {
try {
const response = await s3Client.send(
new GetObjectCommand({
Bucket: 'bucket-name',
Key: 'test/app.json'
})
)
console.log(response)
} catch (error) {
throw new Error(error)
}
}
getS3ObjectV3()
上記をご覧いただければわかる通り、関数の使用方法が変更されただけで基本的なデータの流れはバージョン2と遜色ないものが多いです。
AWS SDK for JavaScript V3 API リファレンスガイドで各サービスや関数ごとに情報が記載されているので、詳しくはそちらをご参照ください。
個人的にうれしい変更点が非同期処理を行う場合の記述です。
上記のようなasync/awaitの記述を行う際、バージョン2ではgetObject
の処理結果から明示的にpromise()
を実行する必要があったのが、client.send(new Command())
の形で記述することで、より簡潔に行えるようになりました。
上記のような処理ではリクエストの結果を元に任意の処理を行うことも多いので、非常にありがたいですね。
v3における注意点
前項のようにバージョン2の記述と互換性のあるものであれば問題はありませんが、処理によってはそうでないものも存在します。
前項同様、S3での処理を見てみましょう。
index.jsimport { S3 } from 'aws-sdk'
const s3Client = new S3({
maxRetries: 10
})
バージョン2ではmaxRetries
という値を指定することで処理の再試行回数の指定ができました。
しかし、バージョン3では上記のmaxRetries
はmaxAttempts
に名前が変更されています。
index.jsimport { S3Client } from '@aws-sdk/client-s3'
const s3Client = new S3Client({
maxAttempts: 10
})
上記のように単純に名称変更のみで対応できるもの以外にも、非推奨となり使用できなくなった機能や型定義が変更されているものもあるので、書き換えを行う際には注意が必要です。
AWS SDKのリポジトリに変更点をまとめてあるので、AWS SDK for JavaScript V3 API リファレンスガイドと合わせて使用する機能をしっかり確認した上で書き換えを行ってください。
まとめ
AWSは本サイトで掲載している案件でも非常に多くの企業が採用しているように、今後もそれらを扱える人材の価値は高まっていくと思います。
今回ご紹介した「AWS SDK for JavaScript」バージョン3を始め、AWSは新たなサービスのリリースや機能のアップデートを繰り返しているので、日々キャッチアップを行って扱える技術の幅を広げていきましょう。