GithubHelp home page GithubHelp logo

serverless-components / express Goto Github PK

View Code? Open in Web Editor NEW
377.0 7.0 34.0 1.99 MB

⚡ Take existing Express.js apps and host them easily on cheap, auto-scaling, serverless infrastructure (AWS Lambda and AWS HTTP API).

Home Page: https://serverless.com/components

License: Apache License 2.0

JavaScript 98.73% TypeScript 1.27%
serverless serverless-framework serverless-components express serverless-express aws-lambda aws aws-http-api nodejs

express's Introduction

Serverless Components


Serverless Express ⎯⎯⎯ This Serverless Framework Component enables you to take existing Express.js apps and deploy them onto cheap, auto-scaling, serverless infrastructure on AWS (specifically AWS HTTP API and AWS Lambda), easily. It's packed with production-ready features, like custom domains, SSL certificates, canary deployments, and costs an average of $0.000003 per request.


  • Never Pay For Idle - No HTTP requests, no cost. Averages ~$0.000003 per request.
  • Zero Configuration - All we need is your code, then just deploy (advanced config options are available).
  • Fast Deployments - Deploy changes to the cloud in seconds.
  • Realtime Logging - Rapidly develop on the cloud w/ real-time logs and errors in the CLI.
  • Canary Deployments - Deploy your app gradually to a subset of your traffic overtime.
  • Custom Domain + SSL - Auto-configure a custom domain w/ a free AWS ACM SSL certificate.
  • Team Collaboration - Collaborate with your teamates with shared state and outputs.
  • Built-in Monitoring - Monitor your express app right from the Serverless Dashboard.

Check out the Serverless Fullstack Application for a ready-to-use boilerplate and overall great example of how to use this Component.

Get Started:

  1. Install
  2. Initialize
  3. Deploy
  4. Configure
  5. Dev Mode
  6. Monitor
  7. Remove

Extra:

 

Install

To get started with this component, install the latest version of the Serverless Framework:

$ npm install -g serverless

After installation, make sure you connect your AWS account by setting a provider in the org setting page on the Serverless Dashboard.

Initialize

The easiest way to start using the express component is by initializing the express-starter template. Just run this command:

$ serverless init express-starter
$ cd express-starter

This will also run npm install for you. You should now have a directory that looks something like this:

|- app.js
|- node_modules
|- package.json
|- serverless.yml

Deploy

Once you have the directory set up, you're now ready to deploy. Just run serverless deploy from within the directory containing the serverless.yml file. Your first deployment might take a little while, but subsequent deployment would just take few seconds. After deployment is done, you should see your express app's URL. Visit that URL to see your new app live.

Note: If you see an internal server error, it probably means you did not run npm install after serverless create. See above for more info.

For more information on what's going on during deployment, you could specify the serverless deploy --debug flag, which would view deployment logs in realtime.


Configure

The Express component is a zero configuration component, meaning that it'll work out of the box with no configuration and sane defaults. With that said, there are still a lot of optional configuration that you can specify.

Here's a complete reference of the serverless.yml file for the express component:

component: express               # (required) name of the component. In that case, it's express.  You will want to pin this to a specific version in production via semantic versioning, like this: [email protected].  Run 'serverless registry express' to see available versions.
name: express-api                # (required) name of your express component instance.
org: serverlessinc               # (optional) serverless dashboard org. default is the first org you created during signup.
app: myApp                       # (optional) serverless dashboard app. default is the same as the name property.
stage: dev                       # (optional) serverless dashboard stage. default is dev.

inputs:
  src: ./                        # (optional) path to the source folder. default is a hello world app.
  memory: 512                    # (optional) lambda memory size.
  timeout: 10                    # (optional) lambda timeout.
  description: My Express App    # (optional) lambda & api gateway description.
  env:                           # (optional) env vars.
    DEBUG: 'express:*'           #            this express specific env var will print express debug logs.
  roleName: my-custom-role-name  # (optional) custom AWS IAM Role name for setting custom permissions.
  traffic: 0.2                   # (optional) traffic percentage to apply to this deployment.
  layers:                        # (optional) list of lambda layer arns to attach to your lambda function.
    - arn:aws:first:layer
    - arn:aws:second:layer
  domain: api.serverless.com     # (optional) if the domain was registered via AWS Route53 on the account you are deploying to, it will automatically be set-up with your Express app's API Gateway, as well as a free AWS ACM SSL Cert.
  vpc:                           # (optional) vpc configuration to apply on the express lambda function
    securityGroupIds:
      - abc
      - xyz
    subnetIds:
      - abc
      - xyz
  region: us-east-2              # (optional) aws region to deploy to. default is us-east-1.

Once you've chosen your configuration, run serverless deploy again (or simply just serverless) to deploy your changes.

Dev Mode

Now that you've got your basic express app up and running, it's time to develop that into a real world application. Instead of having to run serverless deploy everytime you make changes you wanna test, run serverless dev, which allows the CLI to watch for changes in your source directory as you develop, and deploy instantly on save.

To enable dev mode, simply run serverless dev from within the directory containing the serverless.yml file.

Dev mode also enables live streaming logs from your express app so that you can see the results of your code changes right away on the CLI as they happen.

Monitor

Anytime you need to know more about your running express instance, you can run serverless info to view the most critical info. This is especially helpful when you want to know the outputs of your instances so that you can reference them in another instance. You will also see a url where you'll be able to view more info about your instance on the Serverless Dashboard.

It also shows you the status of your instance, when it was last deployed, and how many times it was deployed. To dig even deeper, you can pass the --debug flag to view the state of your component instance in case the deployment failed for any reason.

Remove

If you wanna tear down your entire express infrastructure that was created during deployment, just run serverless remove in the directory containing the serverless.yml file. The express component will then use all the data it needs from the built-in state storage system to delete only the relavent cloud resources that it created.

Just like deployment, you could also specify a --debug flag for realtime logs from the express component running in the cloud.

Architecture

This is the AWS serverless infrastructure that is created by this Component:

  • AWS HTTP API - The API Gateway which receives all requests and proxies them to AWS Lambda.
  • AWS Lambda - A single AWS Lambda function runs your Express.js application.
  • AWS IAM - An AWS IAM role is automatically created, if you do not provide a custom one.
  • AWS Route53 - If you enter a domain input and the domain already exists on your AWS account, a Route53 hosted zone will be created and integrated into your API Gateway.
  • AWS ACM SSL Certificate - If you enter a domain input and the domain already exists on your AWS account, a free AWS ACM SSL certificate will be created.

Guides

Setting Up A Custom Domain & SSL Certificate

The Express Component can easily set up a custom domain and free SSL certificate for you.

First, register your custom domain via Route53 on the AWS Acccount you are deploying to.

Next, add the domain to the domain in inputs in serverless.yml, like this:

inputs:
  src: ./
  domain: serverlessexpress.com

You can also use a subdomain:

inputs:
  src: ./
  domain: express.component-demos.com

Run serverless deploy.

Keep in mind, it will take AWS CloudFront and AWS Route53 and DNS up to 24 hours to propagate these changes and make your custom domain globally accessible. However, with recent AWS CloudFront speed increases, your domain should be accessible within ~20 minutes.

Setting up domains registered outside of AWS

If your domain is not on AWS Route53, you will have to set this up manually because the component does not have access to your registrar. Here are the general steps involved:

  1. Create an AWS ACM certificate for your domain. Make sure you set the "Additional Names" field to *.yourdomain.com as well to include all subdomains as well.
  2. After you create the certificate, it should be in a PENDING_VALIDATION status. Now you will need to validate your domain. We suggest you follow the DNS steps by adding the validation CNAME record you see on the AWS console to your domain via your registrar dashboard.
  3. After you add the validation record, it might take a while, but eventually the certificate should change status to ISSUED. Usually it takes around 5 minutes.
  4. Add your domain to the serverless.yml file as shown above and deploy. This step is important as it adds your domain to API Gateway.
  5. Notice the regional url that is returned as an output. Copy this URL, get back to your registrar and add another CNAME record with your domain or subdomain name and a value of this regional url. This ensures that your domain points to that cloudfront URL.
  6. After around 20 mins, your SSL certificate and domain should all be working and pointing to your URL. Keep in mind that if you change the name, stage, app or org properties in serverless.yml, this would result in a completely new instance with a new cloudfront url. This allows you to setup different domains for each stage or instance

Canary Deployments

At scale, when you want to push changes out to a small set of users, Serverless Express offers easy Canary Deployments out of the box!

This enables you to push out a version of your app (containing code changes you deem risky) which is only served to a percentage of traffic that you specificy (0-99%). This allows you to test big changes with little risk.

To perform a canary deployment, first update your code with the potentially risky change.

Next, set a traffic weighting in your serverless.yml inputs:

inputs:
  src: ./
  traffic: 0.5 # 50%

This tells Serverless Express to serve the new (potentially risky) code to 50% of the API requests, and the old (stable) code to the other 50% of requests.

Run serverless deploy. After deployment is complete, 50% of your requests will be randomly handled by the new experimental code.

You can slowly increment the percentage over time, just continue to re-deploy it.

If things aren't working, revert your code to the old code, remove the traffic configuration option, and deploy.

If things are working, keep the new code, remove the traffic configuration option, and deploy.

How To Debug CORS Errors

The Express Component uses AWS HTTP API, which can offer an API with CORS enabled or not enabled based on the headers you set in your code's responses.

For CORS support you do not need to configure it within the HTTP API infrastructure. You have complete control the CORS behavior of your application via setting traditional CORS headers, like this:

/**
 * Configure Express.js Middleware
 */

// Enable CORS
app.use(function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Methods', '*')
  res.header('Access-Control-Allow-Headers', '*')
  res.header('x-powered-by', 'serverless-express')
  next()
})

If you run into a CORS issue, ensure you are setting up your Express app to return the right headers, like above.

THe biggest reason why CORS errors can happen is because users do not capture errors correctly, and then return a correct HTTP response (with the headers above) in that error response. It may look like a CORS error, but actually, your code is crashing and the automatic error response from HTTP API does not contain the CORS headers.

express's People

Contributors

ac360 avatar astuyve avatar eahefnawy avatar eddeee888 avatar germangamboa95 avatar medikoo avatar murvinlai avatar skierkowski avatar zackdotcomputer 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

express's Issues

Is it possible to use SSM Parameter Store alongside with this component?

I'm trying to setup env vars from ssm parameter store following this guide, but it didn't worked as expected.

Using this plugin did not work as well.

The end result is serverless deploying the ${ssm:XPTO} as string instead of fetching the parameter value from ssm.
image

The parameter exist on ssm:
image

And the --debug did not indicate a failed attempt to fetch the ssm parameter:
image

Is this a bug?
Should this be a feature request?
Is this an intentional missing feature?
.. Or, am I doing something wrong?

Thanks! :)

Typescript Support?

Greetings and thanks for this awesome component.

Quick question. How I could use this with TypeScript?

I tried changing the input/src of the serverless.yml to the output of the compliled js, but on sls deploy, the node_modules was not deployed to the lambda.

Any thoughts on that?

Can't deploy - error "Your code size must be less than 200MB."

I'm trying to deploy my app using sls deploy, but recently, I've started getting this error.

$ sls deploy --stage prod --debug
Initializing...
(node:41224) ExperimentalWarning: The fs.promises API is experimental
Action: "deploy" - Stage: "prod" - Org: "___" - App: "____" - Name: "______"

 Error: Your code size must be less than 200MB.  Try using Webpack, Parcel, or AWS Lambda layers to reduce your code size.
    at run (C:\Users\Tomas\AppData\Roaming\nvm\v10.16.0\node_modules\serverless\node_modules\@serverless\platform-client\src\instance.js:295:13)
    at process._tickCallback (internal/process/next_tick.js:68:7)

2s » Serverless » Your code size must be less than 200MB.  Try using Webpack, Parcel, or AWS Lambda layers to reduce your code size.

  Documentation: https://github.com/serverless/components
  Support: https://app.serverless.com/support
  Slack: https://www.serverless.com/slack/

My serverless.yml config is pretty simple:

app: ____
component: [email protected]
name: ______

inputs:
  src:
    src: ./ # this is the root of the app, ie. the folder containing node_modules
    exclude: # exclude the src files - not super important though
      - src

Serverless Framework version:

$ sls --version

serverless ⚡framework

components version: 2.34.9

Node version:

$ node --version
v10.16.0
$ npm --version
6.9.0

The weird part is that a week ago everything was working fine, and I didn't really have too much dependencies that would exceed the 200MB mark. For perspective, I've working in a different project with puppeteer which embeds a whole chrome instance that weighs about 60MB by itself.

This is my package.json:

{
  "name": "____",
  "version": "0.0.1",
  "description": "",
  "scripts": {
    "start": "cross-env NODE_ENV=development ts-node scripts/server.ts",
    "start:dev": "sls dev",
    "start:prod": "cross-env NODE_ENV=production npm run build && ts-node scripts/server.ts",
....
    "build": "npm run clean && tsc",
    "clean": "rimraf dist",
    "test": "cross-env DOTENV_CONFIG_PATH=.env.test mocha",
    "lint": "tsc --noEmit && eslint . --ext \"ts\"",
    "lint:fix": "npm run lint -- --fix",
    "deploy": "npm run build && npm run lint && sls deploy",
    "deploy:prod": "cross-env NODE_ENV=production npm run build && npm run lint && npm test && sls deploy --stage prod"
  },
  "engines": {
    "node": "^10.17.0"
  },
  "license": "ISC",
  "dependencies": {
    "body-parser": "1.19.0",
    "class-transformer": "0.3.1",
    "class-validator": "0.12.2",
    "cors": "2.8.5",
    "envalid": "6.0.2",
    "express": "4.17.1",
    "express-jwt": "6.0.0",
    "express-jwt-authz": "2.4.1",
    "jsonwebtoken": "8.5.1",
    "jwks-rsa": "1.9.0",
    "module-alias": "2.2.2",
    "morgan": "1.10.0",
    "node-fetch": "2.6.1",
    "passport-jwt": "4.0.0",
    "pg": "8.3.3",
    "pg-hstore": "2.3.3",
    "reflect-metadata": "0.1.13",
    "sequelize": "6.1.1",
    "sequelize-typescript": "2.0.0-beta.0",
    "swagger-ui-express": "4.1.4",
    "typescript-ioc": "3.2.2",
    "typescript-rest": "3.0.2",
    "typescript-rest-ioc": "1.0.0",
    "typescript-rest-swagger": "1.1.4"
  },
  "devDependencies": {
    "@types/chai": "4.2.12",
    "@types/cors": "2.8.7",
    "@types/express": "4.17.8",
    "@types/jsonwebtoken": "8.5.0",
    "@types/mocha": "8.0.3",
    "@types/module-alias": "2.0.0",
    "@types/morgan": "1.9.1",
    "@types/node": "14.6.4",
    "@types/node-fetch": "2.5.7",
    "@types/passport-jwt": "3.0.3",
    "@types/pg": "7.14.5",
    "@types/umzug": "2.2.3",
    "@types/validator": "13.1.0",
    "@typescript-eslint/eslint-plugin": "4.1.0",
    "@typescript-eslint/parser": "4.1.0",
    "chai": "4.2.0",
    "cross-env": "7.0.2",
    "dotenv": "8.2.0",
    "eslint": "7.8.1",
    "eslint-config-prettier": "6.11.0",
    "eslint-import-resolver-typescript": "2.3.0",
    "eslint-plugin-import": "2.22.0",
    "eslint-plugin-node": "11.1.0",
    "eslint-plugin-prettier": "3.1.4",
    "eslint-plugin-unicorn": "21.0.0",
    "mocha": "8.1.3",
    "nock": "13.0.4",
    "prettier": "2.1.1",
    "rimraf": "3.0.2",
    "ts-node": "9.0.0",
    "typescript": "4.0.2",
    "umzug": "2.3.0"
  }
}

Also, if I've tried building the app by preinstalling deps using npm ci but it still didn't work.
The only workaround that did work was wiping out ALL my node_modules folder and then installing only production deps just like this:

npm i && npm run build && rimraf node_modules && npm i --production && sls deploy

However it has the downside that it's a pretty CPU and disk (and time) resource-intensive step.

Also, I remember that the previous setup of Serverless Framework for example for AWS Lambda functions, was smart enough to only package the actually used dependencies, not all the node_modules folder, unless you opted out by specifying excludeDevDependencies: false

So, what options do I have? Is this a bug that needs to be addressed on Serverless Framework side? Do I manually need to deplete and reinstall production-only dependencies every time? Or should I setup a webpack config just for this?

Thanks

SLS Login fails without serverless.yml file

Issue:
After running npm install -g serverless@components, then running sls login, I'm seeing the following error show up.

Error:

sls login
 
  Error --------------------------------------------------
 
  Error: The following file could not be found: undefined
      at Object.loadInstanceConfig (/usr/local/lib/node_modules/serverless/node_modules/@serverless/components/src/cli/utils.js:162:11)
      at Object.runningComponents (/usr/local/lib/node_modules/serverless/node_modules/@serverless/components/src/legacy.js:8:32)
      at Object.<anonymous> (/usr/local/lib/node_modules/serverless/bin/serverless.js:32:25)
      at Module._compile (internal/modules/cjs/loader.js:776:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
      at Module.load (internal/modules/cjs/loader.js:643:32)
      at Function.Module._load (internal/modules/cjs/loader.js:556:12)
      at Function.Module.runMain (internal/modules/cjs/loader.js:839:10)
      at internal/main/run_main_module.js:17:11
 
     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com
 
  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              12.6.0
     Framework Version:         1.63.0-components-v2-beta
     Plugin Version:            3.4.1
     SDK Version:               2.3.0
     Components Version:        undefined

I was following the README here, but it looks like you can't sls login before you have a serverless.yml file so it could make sense to switch #2 and #3 to create the template first, setup your org/name/app, then sls login.
Screen Shot 2020-02-24 at 4 14 17 PM

Support for templatized function names

Is there support for customizing the names of functions the express component deploys to include metadata like stage name, etc?

The DynamoDB component supports that by doing something like below - adding a name input field that you can use to override the database name using variables from runtime, as described here. It doesn't appear that this component currently exposes a name input variable that we can manipulate like this?

Doing this:

component: aws-dynamodb
name: pf-user-database
inputs:
  name: ${name}-${stage}
...

Provisions this:
image

Invalid certificate ARN: arn:aws:acm:us-east-1:LAMBDA_ID:certificate/CERTIFICATE_ID. Certificate must be in 'eu-central-1'.

This is my serverless.yaml

component: express
org: orgName
app: appName
name: api
stage: prod

inputs:
  src:
    src: ./src
    hook: npm run build:prod
    dist: ./dist
  domain: api.MY_ROUTE53_DOMAIN.com
  region: eu-central-1

and this is the error output

Initializing...
Action: "deploy" - Stage: "prod" - Org: "orgName" - App: "appName" - Name: "api"
Deploying...
Deploying Express App...
Packaging Express.js application...
Unzipping /tmp/e8ygooh/source.zip...
Files unzipped into /tmp/fd7zly1...
Installing Express + AWS Lambda handler...
Installing Serverless Framework SDK...
Zipping files...
Files zipped into /tmp/iywiid5.zip...
Verifying the default IAM Role found in state exists with the name: api-rjrujf8-lambda-role...
Verifying the meta IAM Role found in state exists with the name: arn:aws:iam::LAMBDA_ID:role/api-rjrujf8-meta-role...
Verifying the AWS Lambda with the ARN: arn:aws:lambda:eu-central-1:LAMBDA_ID:function:api-rjrujf8-function:3 and Name: api-rjrujf8-function found in state exists...
"AWS Lambda function found.  Updating it's configuration and code..."
AWS Lambda version "4" published
AWS Lambda function updated with ARN: arn:aws:lambda:eu-central-1:LAMBDA_ID:function:api-rjrujf8-function:4
Verifying alias "default"...
Alias "default" found. Updating...
Alias "default" updated.
Checking for existing API with ID: rkda8gh0wl
API found. Updating API with ID: rkda8gh0wl...
Add permission to Lambda enabling API Gateway with this ARN to call it: arn:aws:execute-api:eu-central-1:LAMBDA_ID:rkda8gh0wl/*/*
API with ID "rkda8gh0wl" Updated.
Getting Route53 Hosted Zone ID for domain: MY_ROUTE53_DOMAIN
Domain hosted zone id for MY_ROUTE53_DOMAIN is Z06488292F0FY3V47RWQ2
Checking if a certificate for the MY_ROUTE53_DOMAIN domain exists
Certificate for MY_ROUTE53_DOMAIN is in a "ISSUED" status
Verifying Custom Domain exists on API Gateway: api.MY_ROUTE53_DOMAIN...
Custom Domain not found in API Gateway: api.MY_ROUTE53_DOMAIN.  Creating it...
Domain api.MY_ROUTE53_DOMAIN not found in API Gateway. Creating...

 BadRequestException: Invalid certificate ARN: arn:aws:acm:us-east-1:LAMBDA_ID:certificate/CERTIFICATION_ID. Certificate must be in 'eu-central-1'.
    at Object.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:51:27)
    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/rest_json.js:55:8)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)

72s » api » Invalid certificate ARN: arn:aws:acm:us-east-1:LAMBDA_ID:certificate/CERTIFICATION_ID. Certificate must be in 'eu-central-1'.

Is it possible to use EDGE domains?

If not, how can i force the usage of "API Gateway V1"?
I currently get an error when i try to deploy a simple express app with my custom domain

component: express     
name: myname            
org: myorg              
app: myapp                   

inputs:
  src: ./src
  domain: my-cool-domain.com

"Only REGIONAL domain names can be managed through the API Gateway V2 API. For EDGE domain names, please use the API Gateway V1 API. Also note that only REST APIs can be attached to EDGE domain names"

aws does not give me the opprtunity to use regions in r53, i only have acces to the "global" region

not sure how to proceed.

Error deploying "An update is in progress for resource:"

Upon deploying a stack with this component, I now get an error. The exact same deployment worked fine a couple of months ago.

Command run: sls deploy

Output:

serverless ⚡components
Action: "deploy" - Stage: "dev" - Org: "ExampleOrg" - App: "fullstack-app" - Name: "api"

17s › Serverless › The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:us-east-1:example

  Documentation: https://github.com/serverless/components 
  Support: https://app.serverless.com/support 
  Slack: https://www.serverless.com/slack/ 

I believe this is due to the update of Lambda functions to include states from AWS: https://aws.amazon.com/blogs/compute/coming-soon-expansion-of-aws-lambda-states-to-all-functions/.

It would be great if this could be addressed as this is a huge blocker in deploying.

Images not served properly

I'm experiencing the same issue described here. I'd like to test this solution, but right now I'm using this component, and as far as I know it does not provide any configuration to specify these content-types.

I looked into this file and I noticed the server is not being created with any parameter.

My workaround is going to be not using this component and creating the server myself, but I'd like to use this component in the future. Is it possible to add this content-types as a configuration parameter?

changing the path of the lambda

Hello,

How would you change the path to where the lambda is triggered?

For example, you want one deployment at {domain}/graphql. and another {domain}/api.

Thank you.

Node 14 Support

Hello!

I'm attempting to utilize Node 14 on AWS Lambda, but I can't seem to get the component to respect my settings. It looks like the settings might be able to be added here:

Runtime: 'nodejs12.x',
, but I'm not sure if it's on the roadmap.

Thanks!

Streaming logs not working with serverless dev

I'm trying out the serverless dev feature (which is amazing btw!). Auto deploying works perfectly, but I'm unable to see logs.

I tried to add a console.log to the example like this:

app.get('/*', (req, res) => {
  console.log('hello world')
  res.send(`Hello. Request received: ${req.method} - ${req.path}`);
});

but I'm not seeing the "hello world" in the cli output where I ran serverless dev.

I tried to add the CloudWatchFullAccess permission to my serverless IAM user, thinking it was a permission error but it didn't change the result.

Is this deprecated?

The link to serverless.com/components (Wayback Machine) now redirects to the main framework page and there is zero mention of components on the website (aside from blog posts from 2+ years ago). That coupled with ignored PRs, open issues about basic things like support for larger memory lambdas, and the nodejs version still being pinned to 12 makes me assume this is no longer supported.

It would be nice to have an official deprecation instead of leaving up these repos for someone to stumble over and think they will work. Even the basic setup commands don't work:

> serverless init express-starter
Environment: darwin, node 12.22.7, framework 3.7.1, plugin 6.1.5, SDK 4.3.2
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
Serverless command "init express-starter" not found. Run "serverless help" for a list of all available commands.

Adding VPC settings to config

Hello!

I'm trying to use this component in a VPC and since there is no settings for VPC, I have to go to my deployed Lambda and manually add it in. This is fine in the short term but it would be nice to have it built-in as a feature for this component.

Here's what I had to do manually:

  • Deploy the lambda once
  • Attach AWSLambdaVPCAccessExecutionRole to the role that is used by the lambda
  • Edit VPC settings, add VPC, subnet and security groups in the lambda dashboard

Maybe there could be a new input called vpc and looks similar to normal serverless template?

inputs:
  vpc:
      securityGroupIds:
        - securityGroupId1
        - securityGroupId2
      subnetIds:
        - subnetId1
        - subnetId2

Is this something that could potentially be added in this component? Maybe there's an easier way? Happy to discuss this further. :)

How to set Lambda@Edge configuration?

Hi,
I wish to deploy my Express application on Lambda@Edge similar to how @sls-next/serverless-component deploys.
But I didn't find any configurations setting for this.

How should I enable Lambda@Edge for Express serverless-component?

Thanks.

SLS Login fails without certain serverless.yml fields

Issue:
After running npm install -g serverless@components, then creating an empty serverless.yml file and running sls login, I'm seeing the following error show up.

Error:

➜  slspro git:(master) ✗ touch serverless.yml
➜  slspro git:(master) ✗ sls login                           
 
  Type Error ---------------------------------------------
 
  TypeError: Cannot read property 'name' of undefined
      at Object.loadInstanceConfig (/usr/local/lib/node_modules/serverless/node_modules/@serverless/components/src/cli/utils.js:181:21)
      at Object.runningComponents (/usr/local/lib/node_modules/serverless/node_modules/@serverless/components/src/legacy.js:8:32)
      at Object.<anonymous> (/usr/local/lib/node_modules/serverless/bin/serverless.js:32:25)
      at Module._compile (internal/modules/cjs/loader.js:776:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
      at Module.load (internal/modules/cjs/loader.js:643:32)
      at Function.Module._load (internal/modules/cjs/loader.js:556:12)
      at Function.Module.runMain (internal/modules/cjs/loader.js:839:10)
      at internal/main/run_main_module.js:17:11
 
     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com
 
  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              12.6.0
     Framework Version:         1.63.0-components-v2-beta
     Plugin Version:            3.4.1
     SDK Version:               2.3.0
     Components Version:        undefined

I was following the README here, but it looks like you can't sls login before you have certain fields in your serverless.yml file so it could make sense to switch #2 and #3 to create the template first, then explain what fields need to be setup in order to run sls login.

Related issue: #1

serverless@components version is undefined / serverless cli asking for "service/provider"

Issue:
I've installed serverless@components CLI, tried to create a serverless.yml, but am seeing this error.

Try to sls login with npm i serverless@components -g:

➜  slspro git:(master) ✗ sls login
 
  Serverless Error ---------------------------------------
 
  "provider" property is missing in serverless.yml
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com
 
  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              12.6.0
     Framework Version:         1.63.0-components-v2-beta
     Plugin Version:            3.4.1
     SDK Version:               2.3.0
     Components Version:        undefined
   ╭──────────────────────────────────────────────────────────╮
   │                                                          │
   │   Update available 1.63.0-components-v2-beta → 1.64.0    │
   │              Run npm i serverless to update              │
   │                                                          │
   ╰──────────────────────────────────────────────────────────╯

Follow advice of updating to npm i serverless -g:

➜  slspro git:(master) ✗ npm i serverless -g
/usr/local/bin/serverless -> /usr/local/lib/node_modules/serverless/bin/serverless.js
/usr/local/bin/slss -> /usr/local/lib/node_modules/serverless/bin/serverless.js
/usr/local/bin/sls -> /usr/local/lib/node_modules/serverless/bin/serverless.js

> [email protected] postinstall /usr/local/lib/node_modules/serverless
> node ./scripts/postinstall.js
   ┌───────────────────────────────────────────────────┐
   │                                                   │
   │   Serverless Framework successfully installed!    │
   │                                                   │
   │   To start your first project run 'serverless'.   │
   │                                                   │
   └───────────────────────────────────────────────────┘

+ [email protected]
added 2 packages from 3 contributors, removed 34 packages, updated 6 packages and moved 1 package in 15.868s

Try to sls login again:

➜  slspro git:(master) ✗ sls login          
 
  Serverless Error ---------------------------------------
 
  "provider" property is missing in serverless.yml
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com
 
  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              12.6.0
     Framework Version:         1.64.0
     Plugin Version:            3.4.1
     SDK Version:               2.3.0
     Components Core Version:   1.1.2
     Components CLI Version:    1.4.0

In the attached image you can see the line saying "component version: Undefined" and you can see that following the CLI advice and running npm install serverless -g gives the same error. That our component file is missing a "service/provider" which shouldn't be required for components.

Screen Shot 2020-02-24 at 4 26 42 PM

express-graphql as serverless?

I am introducing my self to serverless and came here but can't seem to understand what's difference with serverfull deployed to heroku? see i have this code in serverless:

app.use(
  "/graphql",
  graphqlHTTP(async (request) => {
    // add user context
    console.log("test");
    return {
      schema,
      graphiql: true,
      context: {
        request,
        //user
      },
    };
  })
);

module.exports = app;

and serverfull:

app.use(
  "/graphql",
  graphqlHTTP(async (request) => {
    // add user context
    return {
      schema,
      graphiql: true,
      context: {
        request,
      },
    };
  })
);

app.listen(port, () => console.log(`Listening on port ${port}`));

can somebody tell me if there's an advantage using serverless in express-graphql? my frontend stack is graphql-relay and i am used to express-graphql and want to explore serverless using express-graphql stack but can't seem to find a good resource to do it. as i am reading from this:

At this point, I think it’s worth noting that not everyone agrees that running Express in a serverless function is a good idea. As Paul Johnston explains, if you’re building your functions for scale, it’s best to break each piece of functionality out into its own single-purpose function. Using Express the way I have means that every time a request goes to the API, the whole Express server has to be booted up from scratch — not very efficient. Deploy to production at your own risk.

please clarify me, i don't see graphql in your samples atm

Cookies in lambda integration payload v2

Overview

Hello! I have an express app that handles sessions by using cookies. Pretty standard stuff, something like this:

import cookieParser from "cookie-parser";

const server = express();
server.use(cookieParser());

Problem

When I try to deploy using serverless and this component, it works ( btw love how simple everything is! ). However, my cookies are not forwarded to the server correctly.

Investigation

I spent a bit of time looking through documentations ( and a lot of head scratching / hair pulling ), this is what I found:

  • payload format version 2 seems to extract cookies from headers automatically and put it in cookies field on the event

  • Since aws-serverless-express currently supports v1, we do a small conversion here to make sure that the shape matches. However, the cookies are no longer in the headers so it never gets forwarded to the backend.

Proposed solution

I think in the conversion section of the handler, we should put back the cookies into the headers field.

How to replicate

  • create a new project per documentation
  • use Insomnia to send a request to the endpoint with a cookie
  • cookie is not in headers ( However, if you decode URI component in x-apigateway-event, you'll be able to see the cookies field separate from headers. Because aws-serverless-express keeps the encoded original apigateway event )
  • if we go to api gateway and change the payload integration to v1, remove the conversion code in the deployed lambda, wire up the api gateway with the new lambda, we'll be able to see cookie in the headers because v1 just forwards everything

Hopefully this makes sense. Maybe thre's another way around this and I haven't pulled my hair hard enough to figure it out :)

Support versionFunctions flag

It doesn't look like the Express component supports the Serverless Framework versionFunctions flag (nor is it supported by plugins such as the serverless-prune-plugin) and so my Lambda console is filling up with necessary old versions of the code.

Can you add support for this so I can set it to FALSE and turn off versions?

Deployment fails to find module when upgrading from v1.7.5 to v2.0.3

I wasn't specifying a version for the component in the serverless.yml file and when I deployed, I pulled in the latest version of the component and ran into the following error:

Error: Cannot find module '..'
Require stack:
- /var/task/_express/handler.js
- /var/task/_serverless/handler.js
- /var/runtime/UserFunction.js
- /var/runtime/index.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
    at Function.Module._load (internal/modules/cjs/loader.js:667:27)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/var/task/_express/handler.js:16:9)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)

When I compared the 2 deployment packages (the last known working version and the latest that failed), I noticed the version difference and was able to resolve the issue by rolling back to 1.7.5 by specifying the version in my component property in the serverless.yml file.

The deployment packages look the same at a glance, and my application was bundled/packaged the same in both cases.

The @serverless/platform-client version went from 1.1.6 to 3.8.0 which was interesting but it's hard to tell exactly what is different between the 2 deployments.

I'm happy to provide more information, I'm just not sure what would be useful, but I wanted to report this as an issue.

API Gateway Creates Duplicate Names For Different Stages

Currently the same name is used for the API Gateway API regardless of the stage being deployed. This makes it a lot more difficult to select the production/development API when digging through the AWS console.

It would be great to suffix the stage in the actual name of the API to make browsing the console a lot easier.

Another option would be to use the name provided in the input as described here: https://github.com/serverless/components#variables

AWS API Gateway Data Transfer Charges

Hi Guys,

I'm really sorry if this question doesn't belong here but I cannot even begin to explain how many hours I have wasted trying to solve this issue. I have a serverless express app that is called using an endpoint generated by serverless via the AWS API Gateway. Quite simply this app gets a request, asks another (external) API for some data, and returns about 2MB of data in the response.

I also have an EC2 running in the same AZ (EU-WEST-2) that queries this app via the endpoint url once every 2 seconds. My bill on AWS is going absolutely crazy with 2 charges. The first is:

$0.010 per GB - regional data transfer - in/out/between EC2 AZs or using elastic IPs or ELB

I am pretty sure this is the cost of transferring the data from the Lambda function over to the EC2 and that is absolutely fine. But on top of this I am being billed for the same amount of data from:

$0.090 per GB - first 10 TB / month data transfer out beyond the global free tier.

This is the charge that I cannot for the life of me comprehend. I have spent countless hours confirming that at absolutely no point does any data leave EU-WEST-2. The lifecycle is EC2 making the call -> Lambda queries remote API -> Lambda returns response to EC2.

So the reason I am raising this here is because I'm wondering if there's somehow something to do with serverless that is pulling a copy of the response and therefor causing a data transfer out to the internet? Otherwise I just cannot understand what is going on here.

Thanks.

How to connect to external database?

Hi!

I used to connect to my external databases such as SQL or Mongo outside of the handler function of my previous lambda functions so that the connection was shared between subsequent function calls. Now that I don't have access to my own handler function anymore with this component, what would be the best way to do that?

Problem using domain diff `.com` domains

Hi, I'm trying using a '**********.com.br' domain, but when I run serverless deploy --debug, the following problem occurs

Getting Route53 Hosted Zone ID for domain: .com.br

And creat a certificate for the .com.br in Certificate Manager but this domain doesn't exist

Custom Domain with Cloudflare

Hi there,

I'm wondering there is a way to make this work if our DNS records are on Cloudflare and not Route53?

Thanks.

Async initialisation strategy

Hi,

I am trying to correctly boostrap the lambda so that it waits until the server is ready. I am using apollo-server-express to host a GraphQL endpoint.

With an app.ts similar to:

const app = express()

const startApolloServer = async () => {
  const driver = neo4j.driver(
    NEO4J_URL,
    neo4j.auth.basic(NEO4J_USERNAME, NEO4J_PASSWORD)
  )

  const neoSchema = new Neo4jGraphQL({
    typeDefs,
    driver,
  })

  const server = new ApolloServer({
    schema: neoSchema.schema,
    context: ({ req }) => ({ req }),
  })

  await server.start()

  server.applyMiddleware({ app })

  await new Promise((resolve: (reason?: any) => void) =>
    app.listen({ port: 4000 }, resolve)
  )

  console.log(
    `🚀 Server ready at http://localhost:${PORT}${server.graphqlPath}`
  )

  return { server, app }
}

module.exports = app

This works but obviously when there is a cold start the lambda is not initially ready as startApolloServer has not completed.

I need to await startApolloServer() during module initialisation. Everything I have tried has not achieved the desired result. What is the recommended best practice in this scenario?

Thanks,
Mark

How to add Cognito auth to the API?

This is a question: How can I add an existing Cognito user pool (that I created with a traditional serverless.yml) to the REST Api of this component?

I'm looking for a functionality similar to what AWS Amplify offers. For this I would need this express component to take in a Cognito user pool id or arn for each path. Or is there another way to achieve a protected API with this component?

How to compress (gzip) responses in express

I have used compression in my express application like so:

  const compression = require('compression');
  const app = express();
  app.use(compression());

While running locally all my responses are compressed but when running on serverless using sls deploy or sls dev I get net::ERR_CONTENT_DECODING_FAILED 200
I am assuming that serverless cant perform compression but the headers are set by the compression library and thus this error.

I need to compress my responses. I came across this as well but wasn't able to make it work (Nothing was being compressed).

Here is my serverless.yml

org: rishav394
app: my-app
component: express
name: express-compress


inputs:
  src: ./

Any help is appreciated. Thanks.

The "express" dependency was not found. Did you install "express" it in your source folder via npm.

Hello dear friends,

I was hoping that maybe you could give me a clue as to what I am doing wrong. I deviated from using the template app as I wanted to try this solution on a more realistic use case: deploying an existing express app to AWS lambda. From the original REST API I created just to test this out, the only changes I really had to make in order to have things similar to the template app were

  • Decouple HTTP server and express app (such that there is an app.js that exports the express app)
  • Added webpack to bundle the app and make it smaller

The bundle goes to ./build containing two files (1) app.js and (2) server.js, the latter being irrelevant for what we are trying to accomplish.

As the title shows, when I hit the endpoint after deploying it, I get the following response The "express" dependency was not found. Did you install "express" it in your source folder via npm.

On the AWS Lambda editor, inspecting the code that was deployed, I can see where this response comes from

Screenshot 2020-06-02 at 13 18 30

App.js

import 'regenerator-runtime/runtime'
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
import cors from 'cors'
import express from 'express'
import morgan from 'morgan'
import router from './router'

const app = express()
const isProduction = process.env.NODE_ENV === 'production'

// App setup
app.use(morgan(isProduction ? 'combined' : 'dev'))
app.use(cors())
app.use(cookieParser())
app.use(bodyParser.json({ type: '*/*' }))
router(app)

export default app

serverless.yml

component: express
name: express-api
stage: dev

inputs:
  description: fine-sifter-server-REST
  region: eu-central-1
  env:
    DEBUG: 'express:*'
    DB_CONN: (...)
    CLIENT_SECRET: (...)
  src:
    src: ./
    hook: npm run build:local
    dist: ./build

webpack.config.js

const path = require('path')
const nodeExternals = require('webpack-node-externals')

module.exports = {
  entry: {
    app: './src/app.js',
    server: './src/server.js'
  },
  mode: process.env.NODE_ENV,
  target: 'node',
  externals: [nodeExternals()],
  output: {
    libraryTarget: 'commonjs',
    path: path.resolve(__dirname, 'build'),
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [['env', { targets: { node: '12.17' } }]]
            }
          }
        ]
      }
    ]
  }
}

package.json

{
  "name": "fine-sifter-server-rest",
  "version": "0.0.1",
  "description": "",
  "author": "Benjamin Alexandre de Macedo Barreto",
  "license": "ISC",
  "main": "src/index.js",
  "engines": {
    "node": ">=12.17.0",
    "npm": ">=6.14.5"
  },
  "scripts": {
    "build": "NODE_ENV=production webpack",
    "build:local": "env-cmd -f env-prod.env webpack",
    "start": "node build/server.js",
    "dev": "env-cmd -f env-dev.env nodemon --exec babel-node src/server.js",
    "dev:docker": "env-cmd -f env-docker-dev.env nodemon --exec babel-node src/server.js",
    "docker:dev": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --build",
    "docker:prod": "",
    "db:up": "docker-compose up --build -d",
    "db:down": "docker-compose down",
    "db:seed": "babel-node src/db-tools/seed.js"
  },
  "devDependencies": {
    "@babel/cli": "^7.10.1",
    "@babel/core": "^7.10.2",
    "@babel/node": "^7.10.1",
    "@babel/preset-env": "^7.10.2",
    "babel-loader": "^8.1.0",
    "babel-preset-env": "^1.7.0",
    "env-cmd": "^10.1.0",
    "nodemon": "^2.0.4",
    "regenerator-runtime": "^0.13.5",
    "serverless": "^1.71.3",
    "standard": "^14.3.4",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-node-externals": "^1.7.2"
  },
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.19.0",
    "cookie-parser": "^1.4.5",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "faker": "^4.1.0",
    "jwt-simple": "^0.5.6",
    "lodash": "^4.17.15",
    "mongoose": "^5.9.16",
    "morgan": "^1.10.0",
    "passport": "^0.4.1",
    "passport-jwt": "^4.0.0",
    "passport-local": "^1.0.0"
  },
  "nodemonConfig": {
    "ignore": [
      "dist",
      "node_modules"
    ]
  },
  "standard": {
    "parser": "babel-eslint",
    "ignore": [
      ".dist",
      "node_modules"
    ]
  }
}

EMFILE Errors

Hello,

I've deployed my express app to production and started seeing consistent errors in the logs related to too many open sockets. This led me to the following issue in the aws-serverless-express repo CodeGenieApp/serverless-express#239 which is almost identical to the issue I'm seeing. I believe the root cause is a DNS error and I'm enabling connection pooling to hopefully address that issue.

However, while reviewing that issue I noticed that they recommend not initializing the express server inside of the handler function. I see that the _express/handler.js source code for this component has the same issue creating the server inside of the handler function which is not recommended.

Can we move the createServer call to the global scope as recommended in the linked issue?

For some context, I don't see any issues with the server running under normal load but at peak the application receives around 40k requests a minute and starts to log around 500 errors a minute.

Error messages look like the following

2020-09-12T21:05:59.973Z 60c8a0e0-f3a3-49b5-ba54-80fb1da9e66c ERROR Error: listen EMFILE: too many open files /tmp/server-io7p3itg74o.sock at Server.setupListenHandle [as _listen2] (net.js:1296:21) at listenInCluster (net.js:1361:12) at Server.listen (net.js:1458:5) at startServer (/var/task/_express/node_modules/aws-serverless-express/src/index.js:152:17) at promise (/var/task/_express/node_modules/aws-serverless-express/src/index.js:226:9) at new Promise (<anonymous>) at Object.proxy (/var/task/_express/node_modules/aws-serverless-express/src/index.js:211:14) at Object.exports.handler (/var/task/_express/handler.js:60:42) at Runtime.exports.handler (/var/task/_serverless/handler.js:35:40) at Runtime.handleOnce (/var/runtime/Runtime.js:66:25) { code: 'EMFILE', errno: 'EMFILE', syscall: 'listen', address: '/tmp/server-io7p3itg74o.sock', port: -1 }

2020-09-12T21:05:59.921Z 26b2321b-c97f-424d-ae89-ec74d4a524c0 ERROR Error: connect EMFILE /tmp/server-i5dzkspeeep.sock at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) { errno: 'EMFILE', code: 'EMFILE', syscall: 'connect', address: '/tmp/server-i5dzkspeeep.sock'}

Thanks

Multi-Level Subdomains

When attempting to use this component with a custom, multi-level subdomain (for example, api.micro-service.widget.co) the deployment fails with the error "The domain name to be created is not covered by the provided certificate".

It looks like this is coming from:

const wildcardSubDomain = `*.${instance.state.nakedDomain}`;

Because it's looking for the "naked domain", and attaching the wildcard on the first level subdomain, the certificate ends up being issued for widget.co with an addition name for *.widget.co, neither of which are valid for api.micro-service.widget.co.

Perhaps I'm misunderstanding and there's a workaround or setup step I'm missing. However, if not, I can provide a pull request.

VPC/subnetIds configuration

Hey,

I saw there's a reference to setting up vpc and subnets in the utils.js code but it doesn't seem work to work for me. Is there some reference/example I can use?

Some dynamic template variables don't work

Hi there,
I'm trying to read a config file and read its contents into an ENV variable, however what I'm getting is an original config string partially interpreted. The 'stage' variable gets replaced properly but everything else is not.

Here's my template:

component: express
name: api

inputs:
  roleName: ${output:api-distributions-permissions.name}
  src: ./src
  # domain: api.${env:domain}
  # Environment variables
  env:
    STAGE: ${stage}
    SCHEMA_NAME: ${file(../../environments.yml):environments.${stage}.dbSchemaName}

Resulting function (you may notice how 'stage' was properly replaced with the correct value):

Screenshot 2021-03-17 at 18 58 50

This exact ENV var definition works in a non-component based service, properly reading the file and putting its content as a ENV variable value. It appears that not all of the dynamic variables available for regular services can be used for component-based services. What are the best practices to solve this?

Framework Core: 2.30.3
Plugin: 4.5.1
SDK: 4.2.0
Components: 3.7.4

Thanks in advance!

Possible to use with NestJS ?

Since NestJS is a framework built on express, and this project uses aws-serverless-express which is supposed to work with any express framework, I was hoping there would be a way to use this plugin for NestJS projects.

Any ideas ?

domain setting fails with brazilian domains (.com.br)

When setting the yml with this option:

inputs:
  domain: api.mydomain.com.br

it doesn't behave well due to this method that wrongly gets the naked domain:

/*
 * Extracts the naked second level domain (ie. serverless.com) from
 * the provided domain or subdomain (ie. api.serverless.com)
 *
 * @param ${string} domain - the domain input that the user provided
 */
const getNakedDomain = (domain) => {
  if (!domain) {
    return null;
  }
  const domainParts = domain.split('.');
  const topLevelDomainPart = domainParts[domainParts.length - 1];
  const secondLevelDomainPart = domainParts[domainParts.length - 2];
  return `${secondLevelDomainPart}.${topLevelDomainPart}`;
};

Maybe using a regex based matching would be a better approach.

Express Metrics & Insights

Now that we have component instances monitored on the dashboard, we could take advantage of CloudWatch Insights for components that uses Lambda by running queries specific to each use case. This issue describes the express use case.

Because the express component is not super high level and could be used for multiple use cases, we could offer value mainly at the request, response & error level. However if we're creative enough, I think we can offer great value just by logging the requests, responses and errors. Imo the most relevant data for tracking things down are requests, more so than responses.

Here are some queries, express with function calls, that I think are relevant for express users. These are just off the top of my head and I already feel the value. The more I learn about CloudWatch insights and the kind of queries I can make, the more useful functions we could add here.

Stats Queries

These are queries that provides numbers, metrics or counts.

  • countRequestsByPathAndMethod(path, method)
  • countAuthenticatedRequests()
  • countUnauthenticatedRequests()
  • countRequestsByStatusCode(500)
  • countRequestsByJsonBody({ foo: bar })
  • countRequestsByErrorMessage('something bad happened')
  • countRequestsByErrorCode('NotFound')
  • countFailedRequests()
  • getAverageResponseTime()
  • getMaximumResponseTime()
  • getAverageMemoryUsed()
  • getMaximumMemoryUsed()

Data Queries

These are queries that shows full log data, rather than just metrics.

  • getRequestsByPathAndMethods('/users', 'POST')
  • getAuthenticatedRequests()
  • getUnAuthenticatedRequests()
  • getRequestsByJsonBody({ foo: bar }) - requests that includes this json data in body.
  • getRequestsByStatusCode(500)
  • getRequestsByMinimumResponseTime(200) - requests that took more than 200
  • getRequestsByErrorMessage('internal server error')
  • getRequestsByErrorCode('NotFound')
  • getErrors()

Support up-to-date Lambda 'memory' options

Lambda functions can support a 'memory' configuration of up to 10240 MB but it doesn't look like this component supports this.

If you try to set the 'memory' to '10240' (for example) in Serverless.yml, you get the following error:

Serverless › Deployment failed due to invalid input: "memory" must be one of [128, 192, 256, 320, 384, 448, 512, 576, 704, 768, 832, 1024, 1280, 1536, 1792, 2048, 2240, 2688, 2944, 3008]

Can this component please support the latest range of memory options for Lambda?

"Dev" mode is failing to capture "UnhandledPromiseRejection" errors with `sls dev` mode

sls dev is failing to capture and report UnhandledPromiseRejection errors w/ the Express Component.

This must have something to do with the Express wrapper/packaging.

Recreate:

app.get(`/*`, async (req, res) => {
  await someBrokenPromise()
})

// Error handler
app.use((err, req, res, next) => {
  console.error(err)
  res.status(500).send('Internal Serverless Error')
})

Nothing will show up in the sls dev mode CLI output. However, the error is in CloudWatch, clearly labeled 'UnhandledPromiseRejection' error.

Express.js users can fix this by writing proper Express.js error handling techniques.

app.get(`/*`, async (req, res, next) => {
  try {
    await someBrokenPromise()
  } catch(error) {
    return next(error)
  }
})

// Error handler
app.use((err, req, res, next) => {
  console.error(err)
  res.status(500).send('Internal Serverless Error')
})

It's just not acceptable for us that something shows up in CloudWatch, but not in dev mode :(

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.