A simple, convenient way to invoke aws lambda functions with best practices.
Best practices:
- optional logDebug of input and output
- throw an error if response contains an error object
npm install --save simple-lambda-client
import { invokeLambdaFunction } from 'simple-lambda-client';
const service = 'svc-jobs';
const stage = getStage();
const getJobByUuid = (event: { uuid: string }): Promise<{ job: Job | null }> =>
invokeLambdaFunction({ service, stage, function: 'getJobByUuid', event });
const getJobsByPostal = (event: { postal: string }): Promise<{ jobs: Job[] }> =>
invokeLambdaFunction({ service, stage, function: 'getJobsByPostal', event });
// ...
export const svcJobs = {
getJobByUuid,
getJobsByPostal
}
simple-lambda-client
exports a function that lets you invoke lambda functions with best practices.
You can use this function directly if you want...
import { invokeLambdaFunction } from 'simple-lambda-client';
const result = await invokeLambdaFunction({ service, stage, function, event });
// ...do amazing things with result...
But you'll probably want to create a reusable method with typedefs
export const getJobByUuid = (event: { uuid: string }) =>
invokeLambdaFunction<{ job: Job | null }>({ service, stage, function: 'getJobByUuid', event });
Which makes using that a lot easier
const { job } = await getJobByUuid({ uuid: '__uuid__' });
// ...do amazing things with result...
You may also want to build a full representation of some lambda service under a namespace
export const svcJobs = {
getJobByUuid,
// ...other methods...
};
This adds extra context about "where" the methods lambdas invoking is coming from
import { svcJobs } from '../path/to/client';
const { job } = await svcJobs.getJobByUuid({ uuid: '__uuid__' });
// ...do amazing things with result...
When this library detects that the lambda you called has thrown an error, it automatically parses it and throws an error of class LambdaInvocationError
For example
import { invokeLambdaFunction, LambdaInvocationError } from 'simple-lambda-client';
try {
await invokeLambdaFunction({
service: 'svc-does-not-exist', // 👈 assume this will cause an error
function: 'doAwesomeThing',
stage: 'dev',
event: {},
});
} catch (error) {
expect(error).toBeInstanceOf(LambdaInvocationError) // 👈 error will be an instance of this class
}
When given a logDebug
method, this library emits input and output logs with best practices, to make debugging a breeze.
For example
await invokeLambdaFunction({
service: 'svc-oceans',
function: 'cleanup',
stage: 'dev',
event: {},
logDebug: console.log, // 👈 will now emit logs to the console
});
When given a cache
instance, this library will wrap the lambda invocation with-simple-caching
For example
import { createCache } from 'simple-im-memory-cache';
await invokeLambdaFunction({
service: 'svc-oceans',
function: 'cleanup',
stage: 'dev',
event: {},
cache: createCache(), // 👈 will now cache the response, with a key of [service, function, stage, event]
});
if you're using this client from inside a lambda, ensure that this lambda has permission to invoke other lambdas
# serverless.yml
iamRoleStatements:
- Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:InvokeAsync
Resource: '*' # TODO: constrain to a specific account, region, service, and stage