I. はじめに
こんにちは。
ブリスウェルのSonです。
Lambdaを使ってNode.jsアプリを開発する際、いくつかの困っていることに直面しています。
・複雑なエラー処理の実装
・認証や権限の実装
・安全な環境変数の管理
・パフォーマンス最適化
その改善策としてフレームワークを探していたところ、Middyが良さそうだと感じて、実際に使ってみた。
II. Middyとは
① 概要
AWS LambdaのためのスタイリッシュなNode.jsミドルウェアエンジンです。
Lambdaコードを整理し、重複を外し、ビジネスロジックに集中する。
② メリット
- すぐに使用できる豊富な公式のミドルウェアとユーティリティと一緒に提供されています。
- 最小のコアを保持することで、関数のサイズを小さくし、Cold Startをコントロールします。
- 簡単に拡張できます。
③ 機能紹介
1. warmup
Lambdaのコールドスタートの問題を軽減するために使用されます。
使用例
const middy = require('@middy/core')
const warmup = require('@middy/warmup')
const isWarmingUp = (event) => event.isWarmingUp === true
const lambdaHandler = (event, context, cb) => {
}
export const handler = middy()
.use(warmup({ isWarmingUp }))
.handler(lambdaHandler)
2. do-not-wait-for-empty-event-loop
タイムアウトが発生しないようにするために使用されます。例えば、データベースへの接続する時。
使用例
import middy from '@middy/core'
import doNotWaitForEmptyEventLoop from '@middy/do-not-wait-for-empty-event-loop'
const lambdaHandler = (event, context) => {
}
export const handler = middy()
.use(doNotWaitForEmptyEventLoop({ runOnError: true }))
.handler(lambdaHandler)
3. http-json-body-parser
HTTPリクエストを自動的に解析し、JSON形式の本文をオブジェクトに変換する。
使用例
import middy from '@middy/core'
import httpJsonBodyParser from '@middy/http-json-body-parser'
const lambdaHandler = (event, context) => {
}
export const handler = middy()
.use(httpJsonBodyParser())
.handler(lambdaHandler)
4. validator
自動的に着信イベントと送信レスポンスをカスタムスキーマに対して検証します。
注意のこと:
・eventSchema
またはresponseSchema
の少なくとも1つが必要です。
使用例
import middy from '@middy/core'
import validator from '@middy/validator'
import httpJsonBodyParser from '@middy/http-json-body-parser'
import { transpileSchema } from '@middy/validator/transpile'
const lambdaHandler = (event, context) => {
}
const eventSchema = {
type: 'object',
required: ['body'],
properties: {
body: {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string' },
email: { type: 'string', format: 'email' }
}
}
}
}
export const handler = middy()
.use(httpJsonBodyParser())
.use(
validator({
eventSchema: transpileSchema(eventSchema)
})
)
.handler(lambdaHandler)
5. http-content-encoding
レスポンスのHTTP Content-Encodingヘッダーを設定し、レスポンス本文を圧縮します。
使用例
import middy from '@middy/core'
import httpContentNegotiation from '@middy/http-content-negotiation'
import httpContentEncoding from '@middy/http-content-encoding'
import { constants } from 'node:zlib'
const lambdaHandler = (event, context) => {
}
export const handler = middy()
.use(httpContentNegotiation())
.use(httpContentEncoding({
br: {
params: {
[constants.BROTLI_PARAM_MODE]: constants.BROTLI_MODE_TEXT,
[constants.BROTLI_PARAM_QUALITY]: 7
}
},
overridePreferredEncoding: ['br', 'gzip', 'deflate']
})
.handler(lambdaHandler)
6. http-cors
Cross-Originリクエストを実行するために必要なAccess-Control-Allow-Origin
、Access-Control-Allow-Headers
、および Access-Control-Allow-Credentials
を含むHTTP CORSヘッダーをレスポンスオブジェクトに設定するために使用されます。
使用例
import middy from '@middy/core'
import cors from '@middy/http-cors'
const lambdaHandler = (event, context) => {
}
export const handler = middy()
.use(cors())
.handler(lambdaHandler)
7. secrets-manager
AWS Secrets Managerからパラメーターを取得して、関数ハンドラのcontext
のオブジェクトにアサインされる。
注意のこと
・Lambdaは、secretsmanager:GetSecretValue
のIAM権限を持っている必要があります。
使用例
import middy from '@middy/core'
import secretsManager from '@middy/secrets-manager'
const lambdaHandler = (event, context) => {
}
export const handler = middy()
.use(
secretsManager({
fetchData: {
apiToken: 'dev/api_token'
},
awsClientOptions: {
region: 'us-east-1'
},
setToContext: true
})
)
.handler(lambdaHandler)
8. ssm
AWS Systems Manager Parameter Storeからパラメータを取得して、関数ハンドラのcontextのオブジェクトにアサインされる。
注意のこと
・Lambdaは、ssm:GetParameters
のIAM権限を持っている必要があります。
使用例
import middy from '@middy/core'
import { getInternal } from '@middy/util'
import ssm from '@middy/ssm'
const lambdaHandler = (event, context) => {
}
let globalDefaults = {}
export const handler = middy()
.use(
ssm({
fetchData: {
accessToken: '/dev/service_name/access_token',
dbParams: '/dev/service_name/database/'
},
cacheExpiry: 15 * 60 * 1000,
cacheKey: 'ssm-secrets'
})
)
.before(async (request) => {
const data = await getInternal(
['accessToken', 'dbParams', 'defaults'],
request
)
Object.assign(request.context, data)
})
.handler(lambdaHandler)
他のAWSサービスに接続する際に使用するSTS(AWS Security Token Service)資格情報を取得することのようなシーンで使うことがあります。
注意のこと
・sts:AssumeRole
のIAM権限が必要です。
使用例
import middy from '@middy/core'
import sts from '@middy/sts'
const lambdaHandler = (event, context) => {
}
export const handler = middy()
.use(
sts({
fetchData: {
assumeRole: {
RoleArn: '...',
RoleSessionName: ''
}
}
})
)
.handler(lambdaHandler)
III. 終わりに
AWS Lambda開発者が開発プロセスを効率化したいと考えている場合には最適なツールです。
Middyは軽量でモジュール化されたアプローチを採用しており、問題を分離し、重複を減らし、Lambda関数の主要なビジネスロジックに焦点を当てることができます。
AWS Lambdaの開発に強力で柔軟なミドルウェアフレームワークをお探しの場合は、ぜひMiddyをご検討ください。