Skip to content

Instantly share code, notes, and snippets.

@revmischa
Created January 5, 2024 00:47
Show Gist options
  • Save revmischa/3859f2b2ead79fae8b2b15a97b398378 to your computer and use it in GitHub Desktop.
Save revmischa/3859f2b2ead79fae8b2b15a97b398378 to your computer and use it in GitHub Desktop.
Zod + middy + AWS lambda API Gateway
import middy, { MiddlewareObj } from '@middy/core'
import httpErrorHandler from '@middy/http-error-handler'
import httpHeaderNormalizer from '@middy/http-header-normalizer'
import httpJsonBodyParser from '@middy/http-json-body-parser'
import { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2, Handler } from 'aws-lambda'
import { zodValidator } from 'middy-zod-validator'
import { ZodSchema, z, infer as ZInfer } from 'zod'
import { isHttpError } from 'http-errors'
type ApiHandler = (
event: import('aws-lambda').APIGatewayProxyEventV2,
context: import('aws-lambda').Context,
) => Promise<APIGatewayProxyStructuredResultV2>
export const restMiddleware = (handler: ApiHandler) =>
middy(handler).use(httpHeaderNormalizer()).use(httpErrorHandler())
export const restZodMiddleware = <T extends ZodSchema>(
schema: T,
// event.body JSON is parsed as T
handler: Handler<Omit<APIGatewayProxyEventV2, 'body'> & { body: ZInfer<T> }, APIGatewayProxyStructuredResultV2>,
) =>
restMiddleware(
handler
)
.use(httpJsonBodyParser())
.use(errorStringifier)
.use(zodBodyValidator(schema))
.use(httpErrorHandler())
export const bodySchema = (schema: ZodSchema) =>
z.object({
body: schema,
})
export const zodBodyValidator = (schema: ZodSchema) => zodValidator(bodySchema(schema))
/**
* If the error is not a string, stringify it.
* This fixes zod errors not being returned as JSON strings.
*/
export const errorStringifier: MiddlewareObj = {
onError: async (handler) => {
if (isHttpError(handler.error) && handler.error && typeof handler.error !== 'string') {
handler.response = {
statusCode: handler.error.statusCode,
body: JSON.stringify(handler.error),
}
}
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment