Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(parser): add docs for parser utility #1835

Merged
merged 24 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/snippets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"aws-sdk-client-mock": "^3.0.0",
"aws-sdk-client-mock-jest": "^3.0.0",
"axios": "^1.5.0",
"hashi-vault-js": "^0.4.14"
"hashi-vault-js": "^0.4.14",
"zod": "^3.22.4"
}
}
32 changes: 32 additions & 0 deletions docs/snippets/parser/decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Context } from 'aws-lambda';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { Context } from 'aws-lambda';
import type { Context } from 'aws-lambda';

import { LambdaInterface } from '@aws-lambda-powertools/commons';
import { parser } from '@aws-lambda-powertools/parser';
dreamorosi marked this conversation as resolved.
Show resolved Hide resolved
import { z } from 'zod';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

class Lambda extends LambdaInterface {
@parser({ schema: orderSchema })
dreamorosi marked this conversation as resolved.
Show resolved Hide resolved
public async handler(event: Order, _context: Context): Promise<void> {
for (const item of event.items) {
// item is parsed as OrderItem
console.log(item.id);
}
}
}

const myFunction = new Lambda();
export const handler = myFunction.handler.bind(myFunction);
33 changes: 33 additions & 0 deletions docs/snippets/parser/envelopeDecorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Context } from 'aws-lambda';
import { LambdaInterface } from '@aws-lambda-powertools/commons';
import { parser } from '@aws-lambda-powertools/parser';
am29d marked this conversation as resolved.
Show resolved Hide resolved
import { z } from 'zod';
import { eventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

class Lambda extends LambdaInterface {
@parser({ schema: orderSchema, envelope: eventBridgeEnvelope }) // (1)!
public async handler(event: Order, _context: Context): Promise<void> {
for (const item of event.items) {
// item is parsed as OrderItem
console.log(item.id); // (2)!
}
}
}

const myFunction = new Lambda();
export const handler = myFunction.handler.bind(myFunction);
34 changes: 34 additions & 0 deletions docs/snippets/parser/envelopeMiddy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Context } from 'aws-lambda';
import { parser } from '@aws-lambda-powertools/parser/middleware';
import { z } from 'zod';
import middy from '@middy/core';
import { eventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

const lambdaHandler = async (
event: Order,
_context: Context
): Promise<void> => {
for (const item of event.items) {
// item is parsed as OrderItem
console.log(item.id);
}
};

export const handler = middy(lambdaHandler).use(
parser({ schema: orderSchema, envelope: eventBridgeEnvelope })
);
21 changes: 21 additions & 0 deletions docs/snippets/parser/examplePayload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "0",
"id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718",
"detail-type": "OrderPurchased",
"source": "OrderService",
"account": "111122223333",
"time": "2020-10-22T18:43:48Z",
"region": "us-west-1",
"resources": ["some_additional"],
"detail": {
"id": 10876546789,
"description": "My order",
"items": [
{
"id": 1015938732,
"quantity": 1,
"description": "item xpto"
}
]
}
}
37 changes: 37 additions & 0 deletions docs/snippets/parser/extend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Context } from 'aws-lambda';
import { LambdaInterface } from '@aws-lambda-powertools/commons';
import { parser } from '@aws-lambda-powertools/parser';
import { z } from 'zod';
import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

const orderEventSchema = EventBridgeSchema.extend({
detail: orderSchema, // (1)!
});

type OrderEvent = z.infer<typeof orderEventSchema>;

class Lambda extends LambdaInterface {
@parser({ schema: orderEventSchema }) // (2)!
public async handler(event: OrderEvent, _context: Context): Promise<void> {
for (const item of event.detail.items) {
// process OrderItem
console.log(item); // (3)!
}
}
}

const myFunction = new Lambda();
export const handler = myFunction.handler.bind(myFunction);
30 changes: 30 additions & 0 deletions docs/snippets/parser/manual.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Context, EventBridgeEvent } from 'aws-lambda';
import { z } from 'zod';
import { eventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
import { EventBridgeSchema } from '@aws-lambda-powertools/parser/schemas';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

export const handler = async (
event: EventBridgeEvent<string, unknown>,
_context: Context
): Promise<void> => {
const parsedEvent = EventBridgeSchema.parse(event); // (1)!
console.log(parsedEvent);

const orders: Order = eventBridgeEnvelope(event, orderSchema); // (2)!
console.log(orders);
};
33 changes: 33 additions & 0 deletions docs/snippets/parser/middy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Context } from 'aws-lambda';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { Context } from 'aws-lambda';
import type { Context } from 'aws-lambda';

import { parser } from '@aws-lambda-powertools/parser/middleware';
import { z } from 'zod';
import middy from '@middy/core';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>;

const lambdaHandler = async (
event: Order,
_context: Context
): Promise<void> => {
for (const item of event.items) {
// item is parsed as OrderItem
console.log(item.id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use our Logger instead, it just adds a couple extra lines.

}
};

export const handler = middy(lambdaHandler).use(
parser({ schema: orderSchema })
);
21 changes: 21 additions & 0 deletions docs/snippets/parser/refine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { z } from 'zod';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

export const orderSchema = z
.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema).refine((items) => items.length > 0, {
message: 'Order must have at least one item',
}),
optionalField: z.string().optional(),
})
.refine((order) => order.id > 100 && order.items.length > 100, {
message:
'All orders with more than 100 items must have an id greater than 100',
});
16 changes: 16 additions & 0 deletions docs/snippets/parser/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { z } from 'zod';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

export { orderSchema, orderItemSchema };
33 changes: 33 additions & 0 deletions docs/snippets/parser/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Context } from 'aws-lambda';
import { parser } from '@aws-lambda-powertools/parser/middleware';
import { z } from 'zod';
import middy from '@middy/core';

const orderItemSchema = z.object({
id: z.number().positive(),
quantity: z.number(),
description: z.string(),
});

const orderSchema = z.object({
id: z.number().positive(),
description: z.string(),
items: z.array(orderItemSchema),
optionalField: z.string().optional(),
});

type Order = z.infer<typeof orderSchema>; // (1)!

const lambdaHandler = async (
event: Order, // (2)!
_context: Context
): Promise<void> => {
for (const item of event.items) {
// item is parsed as OrderItem
console.log(item.id); // (3)!
}
};

export const handler = middy(lambdaHandler).use(
parser({ schema: orderSchema })
);
2 changes: 2 additions & 0 deletions docs/snippets/tsconfig.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this workspace (docs/snippets) to recognize the imports under @aws-lambda-powertools/parser we need to add the aliases to the paths section like done for the other utilities.

In the future we should instead just install the Powertools utilities as dependencies, but for now this is required.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"rootDir": "./",
"baseUrl": ".",
"noEmit": true,
"noUnusedLocals": false,
"allowUnusedLabels": true,
"paths": {
"@aws-lambda-powertools/parameters/ssm": [
"../../packages/parameters/lib/ssm"
Expand Down
Loading