Coder Social home page Coder Social logo

nearst / laconia Goto Github PK

View Code? Open in Web Editor NEW
321.0 321.0 30.0 9.72 MB

Create well-crafted serverless applications, effortlessly.

Home Page: http://laconiajs.io

License: Apache License 2.0

JavaScript 97.34% TypeScript 2.66%
aws aws-lambda javascript node nodejs serverless

laconia's People

Contributors

allcontributors[bot] avatar ankcorn avatar ceilfors avatar dependabot-preview[bot] avatar dependabot[bot] avatar fossabot avatar geoffdutton avatar greenkeeper[bot] avatar hugosenari avatar joeleg avatar ljcoomber avatar mpxr avatar ruden-estolonio-maya avatar sakthivel-tw avatar snyk-bot avatar strernd avatar tschoffelen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laconia's Issues

An in-range update of aws-sdk is breaking the build 🚨

The devDependency aws-sdk was updated from 2.424.0 to 2.425.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

aws-sdk is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for Release v2.425.0

See changelog for more information.

Commits

The new version differs by 2 commits.

  • 7bff3d5 Updates SDK to v2.425.0
  • 0cd8bdc add cors support for IAM and ResourceGroups services (#2584)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

APIGateway Websocket support

There seems to be no support for websocket calls with the current API-Gatewat Adapter

Handler and serverless.yml: https://gist.github.com/Strernd/ead6308cec5b1ef557ce45995c676ed4

https://xxx.execute-api.eu-central-1.amazonaws.com/dev/laconia?hello=world
returns

{
  "body": null,
  "hello": "world"
}

> wscat -c wss://xxx.execute-api.eu-central-1.amazonaws.com/dev
> {action: "laconia"}
returns

< {"message": "Internal server error", "connectionId":"Zq0lpfIyliACGbQ=", "requestId":"Zq1LaGLQliAFsbA="}

I will try to look into the problem and to make a PR, but currently I'm a bit lost on how to do it.

Acceptance test run in PRs

Story

As a contributor,
I would like to run acceptance test before my Pull Request is merged,
So that I can gain more confidence that my commits are not breaking anything

Acceptance criteria

Acceptance test is running in pull request

Additional context

  • This issue is related to #99
  • The concern for contributors at the moment is the need for an AWS account to run this
  • Is there a better way for us to gain confidence without running the test in the cloud?

Generate a unique number

Story

As a developer,
I would like to be able to generate a sequence number easily,
So that I don't need to revert to RDBMS just to generate a unique sequence
Or spend a long time making this work by reading blogs

Discussion

  • How might laconia.js help this? How might the API look like?
    • Should a sequence be generated by API Gateway? See this article
  • DynamoDB can be used to generate sequences. What's everyone thoughts of make this easy for developer to do this?
    • There was also scaling issue i.e. we need to make sure that sequences can be generated in parallel by supporting multiple rows.

serverless-offline raises warning due to callback usage

Describe the bug
This bug is originally raised by @Strernd on gitter. When Laconia is used together with serverless-offline, it is raising a warning.

To Reproduce
Use Laconia with serverless-offline

Expected behavior
A clear and concise description of what you expected to happen.

Actual behavior
A warning message generated by serverless-offline:

Serverless: Warning: handler 'laconia-handler' returned a promise and also uses a callback! | This is problematic and might cause issues in your lambda.

Additional context
The callback is originally retained even though we support node 8 because of a problem in AWS Lambda. Seems like this problem is now fixed, see: https://stackoverflow.com/a/51988695/2464295

Enforce consistent commit messages

Story
As a maintainer,
I would like to have our repository commit message to be consistent,
So that it is more readable
And I can spend my time less on generating release notes

Acceptance Criteria

  • Commit messages made by anyone and bots are consistently formatted

Additional context

  • Check out Angular's convention. Which in turns, check out commitizen and semantic release
  • Will commitizen work with lerna?
  • Dependabot supports semantic commit message too

Retrieve secrets from secret manager

Story

As a developer,
I would like laconia to support secret manager,
So that I can retrieve secrets from secret manager easily, just like how it's supporting SSM at the moment

Acceptance Criteria

  • Able to retrieve secrets from secret manager
  • When there are multiple secrets configured, ensure that they are retrieved in batch

An in-range update of aws-sdk is breaking the build 🚨

The devDependency aws-sdk was updated from 2.403.0 to 2.404.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

aws-sdk is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for Release v2.404.0

See changelog for more information.

Commits

The new version differs by 1 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Make envVarInstances API more explicit

Currently, there is only one way to register invoker and config to LaconiaContext, which is via envVarInstances. After gathering offline feedback, developers found that it is not clear what the factory is doing most of the times when reading the handler code. They also have to jump back and forth from the handler to serverless.yml to make sure that they're using the right variable names.

In conjunction, Laconia still would like to encourage the use of environment variable, so that those values are not hardcoded in the Lambda code.

Summary

  • Rename envVarInstances() to scanEnvVar(). This factory will scan environment variables with LACONIA_ prefixes.
  • Introduce fromEnvVar(["MY_LAMBDA"]). This factory will take the specified environment variable names and create the instance name based on them.
  • Introduce mapEnvVar({MY_LAMBDA: myOwnName}): This factory will take the mapping specified and create the instance names appropriately.

Example

Using scanEnvVar

/**
 * LambdaEnvironment variables:
 * - LACONIA_CONFIG_SOME_SECRET: ssm://path/to/secret
 */
const config = require("@laconia/config");
const laconia = require("@laconia/core");

const app = async ({ someSecret }) => {
  /* logic */
};

exports.handler = laconia(app).register(config.scanEnvVar());

Using fromEnvVar

/**
 * LambdaEnvironment variables:
 * - SOME_SECRET: ssm://path/to/secret
 */
const config = require("@laconia/config");
const laconia = require("@laconia/core");

const app = async ({ someSecret }) => {
  /* logic */
};

exports.handler = laconia(app).register(config.fromEnvVar(["SOME_SECRET"]));

Using fromEnvVar

/**
 * LambdaEnvironment variables:
 * - SOME_SECRET: ssm://path/to/secret
 */
const config = require("@laconia/config");
const laconia = require("@laconia/core");

const app = async ({ mySecret }) => {
  /* logic */
};

exports.handler = laconia(app).register(config.mapEnvVar({ mySecret: "SOME_SECRET" }));

Adopt adapter pattern in @laconia/event

Following the convention that we now have at #13, we should also make the concept of event handler and adapter explicit in the rest of laconia adapters.

Current

const laconiaEvent = require("@laconia/event").s3Json();

const handler = async (object, laconiaContext) => {};

module.exports.handler = laconiaEvent(handler);

Proposed change

const laconia = require("@laconia/core");
const s3 = require("@laconia/event").s3({ inputType: 'object' });

const app = async (object, laconiaContext) => {};

exports.handler = laconia(s3(app));

An in-range update of aws-sdk is breaking the build 🚨

The devDependency aws-sdk was updated from 2.413.0 to 2.414.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

aws-sdk is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for Release v2.414.0

See changelog for more information.

Commits

The new version differs by 3 commits.

  • ab6cdc4 Updates SDK to v2.414.0
  • 91cda83 Revert "allow sending body for GET request of REST services (#2562)" (#2564)
  • 701aff0 allow sending body for GET request of REST services (#2562)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

@laconia/event API is not clear

The way we use @laconia/event currently looks like this:

const laconia = require("@laconia/core");
const event = require("@laconia/event");
 
const app = async (s3Object, laconiaContext) => {
  console.log(s3Object);
};
 
module.exports.handler = laconia(app).register(event.s3Json());

There are few issues with the code above:

  1. We are registering event.s3Json(), but it is not a dependency that will be retrieved from LaconiaContext by the user
  2. The first parameter of app is changed from event to s3Object. This is not explicit enough.

Proposed change:

const laconiaEvent = require("@laconia/event").s3Json();
 
const app = async (s3Object, laconiaContext) => {
  console.log(s3Object);
};
 
module.exports.handler = laconiaEvent(app);

Run acceptance-test in build pipeline

Story
As a maintainer,
I would like the acceptance test to be running in our build pipeline,
So that I don't have to run it manually every time I want to make a new release or merging a new pull request

Acceptance Criteria

  • npm run test:acceptance to be running on every pull requests
  • Setup must be secure that AWS credentials can't be stolen in fork

Additional context

Laconia's acceptance test is currently running in the cloud. This means two things:

  • Contributors might not be interested to run it, because it will involve cost and cloud setup. (Although, seems like all the services we use are falling under free tier?)
  • We need AWS credentials to run the acceptance test. There is a security risk when we're setting the credentials on fork, i.e. attacker can create a new pull request that console.log our environment variables.

An in-range update of p-wait-for is breaking the build 🚨

The dependency p-wait-for was updated from 3.0.0 to 3.1.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

p-wait-for is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for v3.1.0
  • Refactor TypeScript definition to CommonJS compatible export (#9) 03421df

v3.0.0...v3.1.0

Commits

The new version differs by 2 commits.

  • d4aca6d 3.1.0
  • 03421df Refactor TypeScript definition to CommonJS compatible export (#9)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of aws-sdk-mock is breaking the build 🚨

The devDependency aws-sdk-mock was updated from 4.3.1 to 4.4.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

aws-sdk-mock is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Commits

The new version differs by 7 commits.

  • 39e2bf6 add spread syntax to mock service constructor to allow multiple arguments/parameters to be passed in to mocked function/method call. see: #170
  • d4f945b Merge pull request #170 from psaxton/issues/169
  • f8f6b9e Merge pull request #178 from abetomo/update_eslint_rule
  • 0cef307 Update 'space-unary-ops' of eslint
  • 3966cec npm update
  • 3e7fa54 Merge remote-tracking branch 'upstream/master' into origin/issues/169
  • ca17878 Allow constructors with more than 1 parameter to be mocked

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Content-Type determination is case sensitive

The laconia-event/apigateway adapter uses the Content-Type header to determine how to process the body of the request. It does in this in a case-sensitive way although RFC2616 Section 4.2 states "Field names are case-insensitive".

The issue can be replicated by making the Content-Type header name lowercase in the test.

Ease the creation of custom adapters

Laconia must allow developers to design their application primary port without being influenced by Laconia. At the moment, developers restricted to the available adapters. When the built-in adapters not match with their port, it is difficult to re-use the existing Laconia's capability.

For example, if the application is designed as such application(input1, input2, dependencies), Laconia built-in adapters will not be able to handle it.

Summary

  • Introduce @laconia/event package that will allow developers to create their own adapters easily.
  • Use @laconia/event in @laconia/adapter

An in-range update of eslint-plugin-node is breaking the build 🚨

The devDependency eslint-plugin-node was updated from 9.0.1 to 9.1.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint-plugin-node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Commits

The new version differs by 3 commits.

  • 7ce77f9 🔖 9.1.0
  • e5aee3c 🐛 support * in engines.node (fixes #155)
  • fd9d19d no-deprecated-api adheres to targeted node version (fixes #141) (#164)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

How might we abstract DynamoDB?

DynamoDB is an essential part of a serverless architecture in AWS. We read and write data to DynamoDB a lot. Laconia encourages technologists to not be dependent on the cloud in their core application. At the same time, I'm also reluctant to introduce an unnecessary abstraction. Is there a middle ground that covers 80% of user's use cases? How will the API look like if we want to help developers use DynamoDB?

@laconia/api API is not intuitive for Lambda semantics

The way we use @laconia/api currently looks like this:

const laconiaApi = require("@laconia/api");

const app = async ({ req, res }, laconiaContext) => {
  console.log(req);
  const orderId = req.pathParameters.id;
  res.status(200).send({ status: "ok" });
};

module.exports.handler = laconiaApi(app);

In the unit test, we also have to make sure that the API chain is working for res object:

    res = {
      status: jest.fn().mockReturnThis(),
      send: jest.fn()
    };

There are few issues with the code above, mainly it breaks the semantics of writing a Function that should be called with an input and return an output.

  1. The "response" object is not an input.
  2. It's cumbersome to unit test the user application as they have to make a construct of response object
  3. It is okay not to have a return, which is not really intuitive for a Function

Proposed change:

const laconiaApi = require("@laconia/api");
 
const app = async (request, laconiaContext) => {
  return { status: "ok" }
};
 
module.exports.handler = laconiaApi(app);

Originally req, res input style had been adopted as I thought that it'll be very weird not to pass in a response object in the Node.js community, due to the popularity of express.js. Apparently, this is not true:

  1. Fastify: https://www.fastify.io/docs/v2.0.x/Routes/#async-await
  2. Micro: Issue 369

An in-range update of eslint-plugin-import is breaking the build 🚨

The devDependency eslint-plugin-import was updated from 2.16.0 to 2.17.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint-plugin-import is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Commits

The new version differs by 61 commits.

  • 0499050 bump to v2.17.0
  • f479635 [webpack] v0.11.1
  • 8a4226d Merge pull request #1320 from bradzacher/export-ts-namespaces
  • 988e12b fix(export): Support typescript namespaces
  • 70c3679 [docs] make rule names consistent
  • 6ab25ea [Tests] skip a TS test in eslint < 4
  • 405900e [Tests] fix tests from #1319
  • 2098797 [fix] export: false positives for typescript type + value export
  • 70a59fe [fix] Fix overwriting of dynamic import() CallExpression
  • e4850df [ExportMap] fix condition for checking if block comment
  • 918567d [fix] namespace: add check for null ExportMap
  • 2d21c4c Merge pull request #1297 from echenley/ech/fix-isBuiltIn-local-aliases
  • 0ff1c83 [dev deps] lock typescript to ~, since it doesn’t follow semver
  • 40bf40a [*] [deps] update resolve
  • 28dd614 Merge pull request #1304 from bradennapier/feature/typescript-export-type

There are 61 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Inject SSM value while registering instances

I have followed the guide on @laconia/config but I couldn't see an option to inject mySecret while registering instances. A code snippet is as below:

const instances = async () => ({ userService: UserService.build(), });

laconia(handler).register(instances);

Requirement is to provide mySecret to UserService.build(). Currently, I am using aws-sdk inside UserService to get SSM value.

An in-range update of prettier is breaking the build 🚨

The devDependency prettier was updated from 1.17.1 to 1.18.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

prettier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for 1.18.0

🔗 Release Notes

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

How might we abstract S3?

S3 is an essential part of a serverless architecture in AWS. We write and read a lot from S3. Laconia encourages technologists to not be dependent on the cloud in their core application. At the same time, I'm also reluctant to introduce an unnecessary abstraction. Is there a middle ground that covers 80% of user's use cases? How will the API look like?

Make AWS Lambda idempotent

When building on a serverless architecture, it is very common for me to find that I need to make AWS Lambda execution idempotent. This can happen due to various reasons such as error retries, or due to at-least-once delivery event trigger.

Discussion

  • How might laconia.js help developers make AWS Lambda idempotent, and how might the API look like?
  • How is the community handling this at the moment? Is it common to introduce an extra DynamoDB table to ensure idempotency?
  • If a user is already having a separated storage, would introducing an extra table be something that people would do?

Support TypeScript declarations

User Story

As a user of Laconia,
I would like to be able to use Laconia without looking at its documentation
And fully rely on my IDE
So that I can be more productive at work

Acceptance Criteria

  • *.d.ts files are generated for every packages
  • Current API references at laconiajs.io must be generated from the same source

Improving observability with easier debug logs and correlation

As the deployment units and integration with other services are increasing in a serverless architecture, one of the crucial aspect of serverless architecture is observability. In his post here, Yan Cui outlined a couple of points:

  • Track correlation ID across different data sources
  • Enable debug logging throughout a transaction

Discussion

How might Laconia help developers in this area? How might the API look like?

An in-range update of bottleneck is breaking the build 🚨

The dependency bottleneck was updated from 2.17.1 to 2.18.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

bottleneck is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Commits

The new version differs by 3 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Docs for websocket support

Story
As a user,
I would like to see a documentation for laconia's websocket support,
So that I don't need to dig into examples or source codes to see how it work

Acceptance criteria

laconiajs.io to contain the documentation for websocket

Additional context

  • WebSocket support was originally created at #41

Support 'batch' event in laconia-batch

For us to be able to process items in laconia-batch, we can listen to 'item' events. These events only contain individual items. Whenever we have a use case to process item in 'batch', we are going to have to keep an array by ourselves when 'item' events are fired and process them in batch.

Currently supported:

.on('item', (laconiaContext, item) => ... )

Proposed:

.on('batch', (laconiaContext, items) => ... )

An in-range update of prettier is breaking the build 🚨

The devDependency prettier was updated from 1.16.4 to 1.17.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

prettier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ci/circleci: build: Your tests failed on CircleCI (Details).

Release Notes for Prettier 1.17: More quotes options and support for shared configs

🔗 Release Notes

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

WebSocket: Error 500 when using adapter for $connect route

Describe the bug
WebSocket adapter returns 500 without any error. I couldn't find what is causing the error as the error message is swallowed for $connect route.

To Reproduce

serverless.yml

  manage-connection:
    handler: src/manage-connection.handler
    events:
      - websocket:
          route: $connect

handler code:

const laconia = require("@laconia/core");
const adapterApi = require("@laconia/adapter-api");

const app = async () => {};
const webSocket = adapterApi.webSocket();

exports.handler = laconia(webSocket(app));

Expected behavior

  1. Return 200 as $connect is a happy path
  2. Error message should be surfaced to the user

Actual behavior

  1. Return 500
  2. Error message is swallowed, I needed to go to createWebSocketAdapter.js and put a console.log inside catch block

The error message:

2019-06-02T19:48:59.072Z	296c7fe1-bf76-44bb-a958-79f9351af52e	TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.
at Function.Buffer.from (buffer.js:183:11)
at module.exports.event (/var/task/node_modules/@laconia/adapter-api/node_modules/@laconia/event/src/apigateway/getBody.js:2:10)
at module.exports.event (/var/task/node_modules/@laconia/adapter-api/node_modules/@laconia/event/src/apigateway/parseWebSocket.js:5:16)
at fromRaw (/var/task/node_modules/@laconia/adapter-api/node_modules/@laconia/event/src/apigateway/ApiGatewayWebSocketEvent.js:10:7)
at /var/task/node_modules/@laconia/adapter-api/src/createWebSocketAdapter.js:5:30
at laconia (/var/task/node_modules/@laconia/core/src/laconia.js:30:28)
at <anonymous>

WebSocket: Publish message to clients

Continuation of the discussion that we have at #41

As using combining DynamoDB and WebSocket is a common use case, laconia can make users life easier by publishing the below public contracts.

Discussions

  • Is broadcasting a common scenario?
  • If WebSocket is used to reply to individual clients, how do we know which client do we want to retrieve? It looks like there's an additional info from the user land that we need to store if we want to support this

On connect / disconnect

const { websocketHandler } = require('@laconia/websocket')

// Understands event type of $connect and $disconnect, automatically store and delete connection ID in DynamoDB
exports.handler = websocketHandler('WEBSOCKET_CONNECTION_TABLE_NAME')

On sending message
API is inspired from: https://github.com/websockets/ws

const { createWss } = require("@laconia/websocket");

// wss object is injected
const app = async (event, { wss }) => {
  // Automatically get all client objects from DynamoDB
  const clients = await wss.getClients()

  // Sends data to a client, wraps apigwManagementApi
  // What's the best way to find the client here?
  await clients[0].send("something")

  // Broadcast, also wraps apigwManagementApi
  await Promise.all(clients.map(c => c.send('something')))
  await wss.broadcast('something')
};

exports.handler = laconia(app).register(createWss('WEBSOCKET_CONNECTION_TABLE_NAME'));

Invoker dependency is undefined

When combining @laconia/invoker CoC and @laconia/core IoC destructuring, it is difficult to know why my dependency is undefined:

Environment variable:

LACONIA_INVOKER_CAPTURE_CARDPAYMENT: captureCardPayment

Code

module.exports.handler = laconiaBatch(
  _ =>
    laconiaBatch.dynamoDb({
...
    })
)
  .register(invoker.envVarInstances())
  .on("item", ({ captureCardPayment }, item) =>
    captureCardPayment.fireAndForget({
      paymentReference: item.paymentReference
    })
  );

Error message:

2018-12-13T06:56:13.417Z	2d4b47ea-fea4-11e8-8be0-23ecc03cd47f
{
    "errorMessage": "Cannot read property 'fireAndForget' of undefined",
    "errorType": "TypeError",
    "stackTrace": [
        "AsyncFunction.module.exports.handler.laconiaBatch.register.postProcessor.on (/var/task/src/process-card-payments.js:18:23)",
        "emitTwo (events.js:126:13)",
        "AsyncFunction.emit (events.js:214:7)",
        "BatchProcessor.from.on.args (/var/task/node_modules/@laconia/batch/src/laconiaBatch.js:8:40)",
        "emitOne (events.js:116:13)",
        "BatchProcessor.emit (events.js:211:7)",
        "BatchProcessor.start (/var/task/node_modules/@laconia/batch/src/BatchProcessor.js:27:14)",
        "<anonymous>"
    ]
}

Various causes:

  • There is a missing underscore in the environment variable name LACONIA_INVOKER_CAPTURE_CARDPAYMENT.
  • I might forget to register invoker.envVarInstances()

Lifecycle hooks

Recently I've got a use case of trying to execute something before a Lambda times out. This made me think of a lifecycle that I should have been able to listen to, for example, it may look like this:

laconia(app)
  .register(...)
  .on('30sBeforeTimeout', () => { /* do something * / })

Discussion

  • Is this something that we should introduce?
  • What other lifecycle hooks that developers may find useful here?
  • Should the API be using .on(string)? I felt that a string makes it too easy for developers to have a typo. How might the API look like?

Lambda function does not finish and times out

Describe the bug
Hi there. I've been enjoying using Laconia for my lambda-based project, thanks for developing it.

I'm encountering an issue where my Lambda function executes properly, and I can see from the logs that it reaches the final line of the function (the return statement). However lambda doesn't seem to be aware that the function has finished, so it hangs until the configured timeout and then throws a timeout error.

To Reproduce
Here's a "toy" summary of my code:

import laconia from '@laconia/core';
import myAdaptor from 'Adaptors/myAdaptor';
import getDbConfig from 'Infrastructure/database/getDbConfig';
import connect from 'Infrastructure/database/connect';

const factory1 = async () => ({ dbConfig: await getDbConfig() });
const factory2 = async ({ dbConfig }) => ({
  connection: await connect(dbConfig),
});

const app = async (event, { connection }) => {
 let result;
  try {
    result = await connection.performQuery(event);
  } catch (err) {
    console.error('query error: ', err);
    result = err;
  }
  await connection.end();
  console.log('query result: ', result);
  return { result: result };
});

export default laconia(myAdapter(app))
  .register(factory1)
  .register(factory2);

When I invoke this function, the query and logging all happens within 1 second. Then the function waits 10 seconds before returning an error:

{
  "errorMessage": "2019-06-08T17:00:51.417Z SOME_UUID Task timed out after 10.00 seconds"
}

Expected behavior

I'm expecting the function invocation to gracefully terminate at the end of the execution of the logic in the app.

Actual behavior

All logic executed, then the function waits until the timeout.

Additional context
I'm using serverless-mysql as my DB client.

Can't console.log LaconiaContext

Describe the bug
LaconiaContext throws TypeError when it's being console.log-ed.

To Reproduce

const app = (event, lc) => { // not destructured for temporary logging purposes
   console.log(lc)
}

Expected behavior
LaconiaContext should be printed to the console without an error, just like any other plain JS object.

Actual behavior
The following error is thrown:

TypeError: Cannot convert a Symbol value to a string
at checkInstanceName (/var/task/node_modules/@laconia/core/src/LaconiaContext.js:23:25)
at Object.get (/var/task/node_modules/@laconia/core/src/LaconiaContext.js:35:7)
at formatValue (util.js:423:37)
at inspect (util.js:324:10)
at Console.format (util.js:253:18)

Additional context
None

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Cloud integration testing for Lambdas

Integration testing is becoming very important in serverless architecture. This is because our architecture will consist of services that are only available in the cloud. The integration testing though is becoming quite tricky. If you have a Lambda triggered by an S3 change for example, how do you test if it is triggered by an S3 change?

One might argue that I should be using localstack. My experience in localstack is it doesn't give me the confidence of pushing my application to production, as there's no guarantee that it's going to be a "production-like" environment.

Discussion
Currently Laconia has a component for testing which can be found here. It's not documented in laconiajs.io as I'm not confident whether this is something helpful for the community. One thing that I wasn't confident about is the concept of "Remote spying" through S3.

What's everyone's thoughts on this topic? Is "Remote spying" something that the community would find helpful? One pain that I see is also the lack of integration with a deployment tools, which mean I would need developers to create their own S3 bucket before they can use the spy capability.

How else might we help developers on this area?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.