Security News
Bun 1.2 Released with 90% Node.js Compatibility and Built-in S3 Object Support
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.
@laconia/core
Advanced tools
🛡️ Laconia Core — Micro dependency injection framework.
An AWS Lambda handler function is a single entry point for both injecting dependencies and function execution. In non-serverless development, you can and will normally only focus on the latter. This brings a unique challenge to AWS Lambda development as it is very difficult to test a handler function when it is responsible for doing both the object creations and the application run. @laconia/core is a simple dependency injection framework for your Lambda code, hence solving this problem for you.
Laconia explicitly splits the responsibility of the object creations and Lambda function execution. Laconia also provides a simple way for you to execute your Lambda function so that your unit tests will not execute the code that instantiates your Lambda dependencies.
Check out FAQ
One of the problem in AWS Lambda is the UnhandledPromiseRejectionWarning
problem where
you can't throw an error out of your handler function.
By simply using laconia
, you will avoid this common problem.
npm install --save @laconia/core
To fully understand how Laconia's Dependency Injection works, let's have a look into an example below. This is not a running code as there are a lot of code that have been trimmed down, full example can be found in the acceptance test: src and unit test.
Lambda handler code:
// Objects creation, a function that returns an object
const instances = ({ env }) => ({
orderRepository: new DynamoDbOrderRepository(env.ORDER_TABLE_NAME),
idGenerator: new UuidIdGenerator()
});
// Handler function, which do not have any object instantiations
module.exports.handler = laconia(
// Instances made available via destructuring
async ({ event, orderRepository, idGenerator }) => {
await orderRepository.save(order);
}
).register(instances);
Unit test code:
const handler = require("../src/place-order").handler;
// Creates a mock Laconia context
beforeEach(() => {
lc = {
orderRepository: {
save: jest.fn().mockReturnValue(Promise.resolve())
}
};
});
// Runs handler function without worrying about the objects creation
it("should store order to order table", async () => {
await handler.run(lc);
expect(lc.orderRepository.save).toBeCalledWith(
expect.objectContaining(order)
);
});
Note that as you have seen so far, Laconia is not aiming to become a comprehensive DI framework hence the need of you handle the instantiation of all of the objects by yourself. It should theoretically be possible to integrate Laconia to other more comprehensive NodeJS DI framework but it has not been tested.
Laconia provides a one stop location to get all of the information you need for your Lambda
function execution via LaconiaContext
. In a nutshell, LaconiaContext is just an object that
contains all of those information by using object property keys, hence you can destructure it
to get just the information you need.
When Laconia is adopted, the handler function signature will change. Without Laconia,
your handler signature would be event, context, callback
. With Laconia, your handler
signature would be laconiaContext
. The event
and context
are always available in LaconiaContext.
callback
is not made available as this should not be necessary anymore when you are
using Node 8, just return
the value that you want to return to the caller inside the handler function.
Example:
laconia(({ event, context }) => true);
It is very common to set environment variables for your Lambda functions.
This is normally accessed via process.env
. Unit testing a Lambda function that
uses process.env
is awkward, as you have to modify the process
global variable and remember
to remove your change so that it doesn't affect other test.
For better unit testability, LaconiaContext contains the environment variables
with key env
.
Example:
laconia(({ env }) => true);
When #register
is called, all of the instances returned by the function specified will be
cached by default and will expire every 5 minutes. It is therefore a good practice to offload
some of the heavy operations that don't change on every Lambda run to LaconiaContext
.
This feature can be turned off, see API section.
laconia(fn)
fn(laconiaContext)
Function
is called when your Lambda is invokedlaconiaContext
object, which can be destructured to {event, context}
Example:
// Simple return value
laconia(() => "value");
// Return a promise and 'value' will be returned to the Lambda caller
laconia(() => Promise.resolve("value"));
register(factoryFn, options)
Registers objects into LaconiaContext. Objects registered here will be made available in the Lambda function execution.
factoryFn(laconiaContext)
Function
is called when your Lambda is invokedoptions
:
cache
enabled = true
maxAge = 300000
Example:
// Register an object with key 'service'
laconia(({ service }) => service.call()).register(() => ({
service: new SomeService()
}));
// Reduce maxAge
const handler = () => {};
laconia(handler).register(
async () => (
{
/* heavy operations */
},
{
cache: {
maxAge: 1000
}
}
)
);
run(laconiaContext)
Runs Lambda handler function with the specified laconiaContext
and bypasses
the LaconiaContext registration step. This function should only be used in a
unit test.
laconiaContext
// Runs a handler function with a LaconiaContext that contains a mock service object.
// `SomeService` will not be instantiated
laconia(({ service }) => service.call())
.register(() => ({
service: new SomeService()
}))
.run({
service: jest.mock()
});
FAQs
Micro dependency injection framework
We found that @laconia/core demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.
Security News
Biden's executive order pushes for AI-driven cybersecurity, software supply chain transparency, and stronger protections for federal and open source systems.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.