Typescript and decorator ... should we provide a higher order function ? #282
-
Decorator being limited to class level element it might not be that intuitive to use knowing that most lambda handlers are written not in OOP but more functional programming. So just wondering how to present that in term of doc ... import {Metrics, MetricUnits} from '@aws-lambda-powertools/metrics';
import { Callback, Context } from 'aws-lambda';
const metrics = new Metrics({namespace:"CDKExample", service:"withDecorator"});
export class MyFunctionWithDecorator {
@metrics.logMetrics({captureColdStartMetric: true})
public handler(_event: any, _context: Context, _callback: Callback<any>): void | Promise<any> {
metrics.addMetric('test-metric', MetricUnits.Count, 10);
if(_event.throw) {
throw new Error('Test error');
}
}
}
export const handlerClass = new MyFunctionWithDecorator()
export const handler = handlerClass.handler vs. import {Metrics, MetricUnits} from '@aws-lambda-powertools/metrics';
import { Context } from 'aws-lambda';
const metrics = new Metrics({namespace: "CDKExample", service: "MyFunction"});
export const handler = async (_event: any, _context: Context) => {
metrics.addMetric('test-metric', MetricUnits.Count, 10);
metrics.purgeStoredMetrics();
}; vs. Another way would be to go with a wrapper like they do in aws-embedded-metrics-node : const { metricScope } = require("aws-embedded-metrics");
const myFunc = metricScope(metrics =>
async () => {
// ...
});
exports.handler = myFunc; Bottom line : Should we propose a wrapper function for each module ? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 10 replies
-
Agree with you in that most handlers are written as functions and that decorators needing classes make things a bit awkward. It's also clear that using decorators lead to a better DX since there's much less boilerplate (since we do things behind the scenes in the decorator function). In terms of documentation I think that we could limit examples written as OOP only to features that require a decorator and also provide a way of achieving the same without decorator (when possible). All other features that don't involve a decorator could use regular function handlers for the examples. This should clarify that OOP is not a requirement to use Powertools. I guess the question here is also how much (if any) we want to be opinionated and suggest/recommend one over the other. |
Beta Was this translation helpful? Give feedback.
-
Another options would be a set of middlewares : const handler = powertools((event, context) => {
// YOUR LOGIC
}).use(
metricMiddleware({})
) or we propose at launch a middy one ... |
Beta Was this translation helpful? Give feedback.
-
For documentation, I propose to have a 3 tabs view for each part . Example: And have that for each feature (in my case for metrics it would be coldstartmetric, raiseOnEmptymetric, addmetadata etc.) |
Beta Was this translation helpful? Give feedback.
-
I'm in favor of those 3 options. How much development + maintenance effort do we need to support Middy? |
Beta Was this translation helpful? Give feedback.
-
Personally speaking, my vote goes to create a number of configurable middy middleware in each utility that customers can use to wrap their handlers: To add some historical context about decorators vs middleware: when I started working on the libraries my initial plan was to not have decorators and just go for middy middleware directly, as the middy library is well maintained and pretty much the most used one in the node.js ecosystem. No need to reinvent the wheel in my opinion. |
Beta Was this translation helpful? Give feedback.
-
The decision is that we leave it as it is now, and we will let customers share their feedback via issues if they have any. |
Beta Was this translation helpful? Give feedback.
The decision is that we leave it as it is now, and we will let customers share their feedback via issues if they have any.