Code Monkey home page Code Monkey logo

aws-nestjs-starter's Introduction

Serverless, AWS, NestJS, GraphQL and DynamoDB starter

CI Alert Status Coverage Bugs Code Smells License

Description

A starter project that makes creating a deployable AWS Serverless project extremely easy.

Technologies

Usage

git clone https://github.com/hardyscc/aws-nestjs-starter.git <Your_Project_Name>
cd <Your_Project_Name>

npm install

After that find and replace aws-nestjs-starter to your project name on the following files:

  • package.json
  • serverless.yml
  • .env

Setup AWS Credentials

  1. Sign up for an AWS account

  2. Login to your AWS account and go to the Identity & Access Management (IAM) page.

  3. Click on Users and then Add user. Enter a name in the first field to remind you this User is related to the Serverless Framework, like serverless-admin. Enable Programmatic access by clicking the checkbox. Click Next to go through to the Permissions page. Click on Attach existing policies directly. Search for and select AdministratorAccess then click Next: Review. Check to make sure everything looks good and click Create user.

  4. View and copy the API Key & Secret to a temporary place. You'll need it in the next step.

Setup Workstation

Install AWS CLI

  • Windows: choco install awscli
  • MacOS: brew install awscli

Config AWS CLI

$ aws configure

AWS Access Key ID [****************TKYQ]:
AWS Secret Access Key [****************yNO2]:
Default region name [us-east-1]:
Default output format [None]:

Please enter your AWS Access Key ID, AWS Secret Access Key and Default region name

Deployment

# deploy to AWS
$ npm run deploy

Install DynamoDB local

# download dynamodb local into .dynamodb folder
$ npm run ddb:install

Local Offline Development

# start dynamodb local
$ npm run ddb:start

# start serverless-offline server
$ npm run sls:offline

# start serverless-offline server and connect to online dynamodb
$ npm run sls:online

Local NestJS Development - (Optional)

# start dynamodb local
$ npm run ddb:start

# start local nestjs server
$ npm start

# start local nestjs server in watch mode
$ npm run start:watch

# start local nestjs server and connect to online dynamodb
$ npm run start:online

Tools

# re-generate the resources/dynamodb.yml from schemas
$ npm run genres

Unit Testing

# run unit test
$ npm test

# run unit test with coverage
$ npm run test:cov

E2E Testing

# start dynamodb local
$ npm run ddb:start

# run unit test with coverage
$ npm run test:e2e

GraphQL Endpoint Test

mutation {
  createNotification(
    input: { targetId: "device1", userId: "user1", content: "Hello World" }
  ) {
    id
  }
}
query {
  notificationByUserId(userId: "user1") {
    id
    targetId
    userId
    content
    createAt
  }
}
query {
  notificationByTargetId(targetId: "device1") {
    id
    targetId
    userId
    content
    createAt
  }
}
mutation {
  updateNotification(
    id: "1ca7726e-0af8-4ff1-8ef1-4eae97377162"
    input: { status: Deleted }
  ) {
    id
    targetId
    userId
    content
    createAt
  }
}

RESTful Endpoint Test

Please remove /dev from path if test using local nestjs mode

curl -X POST 'http://localhost:3000/dev/notification' \
  -H 'Content-Type: application/json' \
  --data-raw '{ "targetId": "device1", "userId": "user1", "content": "Hello" }'
curl -X GET 'http://localhost:3000/dev/notification?targetId=device1'
curl -X GET 'http://localhost:3000/dev/notification?userId=user1'
curl -X PATCH 'http://localhost:3000/dev/notification/a30f7101-2434-4443-87fa-493c9d9d3358' \
  -H 'Content-Type: application/json' \
  --data-raw '{ "status": "Deleted" }'

Stay in touch

aws-nestjs-starter's People

Contributors

adamlesniak avatar hardyscc avatar renovate-bot avatar renovate[bot] 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

aws-nestjs-starter's Issues

[Enhancement] How can use the pagination in this stack?

I have been using DynamoDB for a long time and use the custom query param LastEvaluatedKey to get the next records list.

however, I can't find that one or a similar query in your source code.

Could you please tell me where is that?

Serverless not finding modules running Nest.js

Everything was fine until I started importing services from other modules, I'm looking for a reference to this error, the error occurs when you run it with lambda, but everything is fine with nest js
image

`service: sales-api-dev

plugins:

  • serverless-plugin-typescript
  • serverless-plugin-optimize
  • serverless-offline
  • serverless-stage-manager

provider:
name: aws
apiGateway:
restApiId: hiden
restApiRootResourceId: hiden
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: arn:aws:dynamodb:${self:provider.region}::

runtime: nodejs14.x
stage: ${opt:stage, 'dev'}
region: us-east-2

package:
exclude:
- .gitignore
- README.md
- serverless.yml
- nest-cli.json
- .prettierrc
excludeDevDependencies: true
individually: true

functions:
main:
handler: src/main.handler
events:
- http:
cors: true
path: '{proxy+}'
method: any

custom:
stages:
- dev
- test
- acc
- prod
serverless-offline:
useChildProcesses: true
`
Any help in this regard would be very helpful, I clarify that it only happens with serverless

Add docker-compose.yml

version: '3'

services:
dynamodb:
image: amazon/dynamodb-local
hostname: dynamodb-local
container_name: dynamodb-local
ports:
- "8000:8000"
command: ["-jar", "DynamoDBLocal.jar", "-sharedDb", "-inMemory"]

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: renovate.json
Error type: The renovate configuration file contains some invalid settings
Message: matchUpdateTypes: matchUpdateTypes should be inside a 'packageRule' only

[Error]: Register Table name in dynamoose when use prefix and transaction

Hi! I worked with your source base. But if i set prefix stg-tableName
DynamoDb created a new table with a prefix. It worked
But the transaction function got an error. All class use transaction or transaction Support got error

Table \"stg-points\" not found. Please register the table with dynamoose before using it in transactions.
@Module({
  imports: [
    ConfigModule.forRoot({ envFilePath: '.env' }),
    DynamooseModule.forRoot({
      logger: false,
      aws: {
        region: process.env.AWS_REGION,
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
      },
      table: {
        create: true,
        waitForActive: true,
        initialize: true,
        update: false,
        tableClass: TableClass.infrequentAccess,
        prefix:
          process.env.NODE_ENV !== 'dev' ? `${process.env.NODE_ENV}-` : '',
      },
    }),
  ],
  providers: [transactionBase, DynamooseModule],
  exports: [transactionBase],
})
export class DynamodbModule {}

My schema

export const LotteryModel: Required<ModelDefinition> = {
  name: ETableName.LOTTERIES,
  schema: new Schema(
    {
      userId: {
        type: String,
        hashKey: true,
      },
      title: {
        type: String,
      },
      quantity: {
        type: Number,
      },
    },
    {
      timestamps: defaultSettings,
    },
  ),
  options: {
    tableName: ETableName.LOTTERIES,
  },
  serializers: {},
};

my module

@Module({
  imports: [
    DynamooseModule.forFeature([LotteryModel, RewardModel]),
    DynamodbModule,
    UserModule,
    PointModule,
  ],
  controllers: [LotteryController],
  providers: [LotteryService, LotteryRepo, RewardRepo],
})
export class LotteryModule {}

Invoke graphql lambda from another lambda

I have two lambda (separate project) developed in nestjs + grapqh. I am trying to call one of the lambda through the other and get responses with the invoke function of aws sdk.

Did the problem come from my way of writing the payload? because I have tried several formats but still no result.
because I noticed that the request is well received by the second lambda, but it may not be able to resolve it.

Tks in advance for your feedback

let lambda = new Lambda({
            apiVersion: '2015-03-31',
            endpoint: process.env.IS_DDB_LOCAL === 'true'
              ? 'http://localhost:3002'
              : 'https://lambda.us-east-1.amazonaws.com',
          });

const params = {
                FunctionName: 'FunctionName', eg: demo-dev-index-function
                InvocationType: 'RequestResponse',
                // Payload: JSON.stringify({ data: 'foo' }),
                Payload: JSON.stringify({
                    query: `{
                            findIdentityWithPhoneNumber(phoneNumber: "99999999") {
                                ObjectId
                                uuid
                            }
                        }`
                }),
            }

const response = await lambda.invoke(params).promise()
console.log(response);

{
  StatusCode: 200,
  Payload: '{"statusCode":404,"body":"{\\"statusCode\\":404,\\"message\\":\\"Cannot GET /\\",\\"error\\":\\"Not Found\\"}","headers":{"x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"63","etag":"W/\\"3f-GR0G8sZfNVmVbqqGkyrPOefU7Ys\\"","date":"Wed, 28 Apr 2021 10:05:40 GMT","connection":"close"},"isBase64Encoded":false}'
}

//serverless.yml for the called function

service: serviceName
useDotenv: true
  
provider:
  lambdaHashingVersion: 20201221
  name: aws
  runtime: nodejs12.x
  memorySize: 256
  stage: ${opt:stage, 'dev'}
  region: ${opt:region}
  environment:
    SERVICE: ${self:service}
    STAGE: ${self:provider.stage}
    REGION: ${self:provider.region}
    VERSION: ${env:VERSION}
    LOCALE: ${env:LOCALE}

  apiGateway:
    shouldStartNameWithService: true
  iam:
    role:
      statements:
        - 
          Effect: "Allow"
          Action:
            - "lambda:InvokeFunction"
          Resource: "*"
        - 
          Effect: Allow
          Action:
            - dynamodb:DescribeTable
            - dynamodb:Query
            - dynamodb:Scan
            - dynamodb:GetItem
            - dynamodb:PutItem
            - dynamodb:UpdateItem
            - dynamodb:DeleteItem
          Resource: arn:aws:dynamodb:${self:provider.region}:*:*

plugins:
  - serverless-plugin-typescript
  - serverless-dynamodb-local
  - serverless-offline

# remove the unnecessary packages to keep small upload size
package:
  patterns:
    - '!node_modules/typescript/**'
    - '!node_modules/@types/**'

custom:
  dynamodb:
    stages:
      - ${self:provider.stage}
    start:
      port: 8000
      inMemory: true
      migrate: true
      seed: false

functions:
  index-function:
    handler: src/index.handler
    events:
      - http:
          cors: true
          path: '{proxy+}'
          method: any

resources:
  - ${file(resource/dynamodb.yml)}

aws-serverless-express NPM package will be deprecated in favor of @vendia/serverless-express

proposed changes:

  1. adopt @vendia/serverless-express
npm uninstall @types/aws-serverless-express
npm uninstall aws-serverless-express
npm i --save @vendia/serverless-express
  1. index.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import serverlessExpress from '@vendia/serverless-express';
import { APIGatewayProxyHandler, Handler } from 'aws-lambda';
import express from 'express';
import { AppModule } from './app.module';

let cachedServer: Handler;

const bootstrapServer = async (): Promise<Handler> => {
	const expressApp = express();
	const app = await NestFactory.create(AppModule, new ExpressAdapter(expressApp));
	app.useGlobalPipes(new ValidationPipe({ forbidUnknownValues: true }));
	app.enableCors();
	await app.init();
	return serverlessExpress({
		app: expressApp
	});
};

export const handler: APIGatewayProxyHandler = async (event, context, callback) => {
	if (!cachedServer) {
		cachedServer = await bootstrapServer();
	}
	return cachedServer(event, context, callback);
};

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): lock file maintenance

Pending Status Checks

These updates await pending status checks. To force their creation now, click the checkbox below.

  • chore(deps): update dependency serverless-offline to v13.3.4
  • fix(deps): update dependency @apollo/server to v4.10.4
  • fix(deps): update nest monorepo to v10.3.8 (@nestjs/common, @nestjs/core, @nestjs/platform-express, @nestjs/testing)

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/nodejs.yml
  • actions/checkout v4
  • actions/setup-node v4
  • actions/upload-artifact v4
  • actions/checkout v4
  • actions/download-artifact v4
  • SonarSource/sonarcloud-github-action v2.1.1
npm
package.json
  • @apollo/server 4.10.3
  • @graphql-tools/merge 9.0.3
  • @nestjs/apollo 12.1.0
  • @nestjs/common 10.3.7
  • @nestjs/config 3.2.2
  • @nestjs/core 10.3.7
  • @nestjs/graphql 12.1.1
  • @nestjs/platform-express 10.3.7
  • @vendia/serverless-express 4.12.6
  • class-transformer 0.5.1
  • class-validator 0.14.1
  • dynamoose 4.0.0
  • graphql 16.8.1
  • husky 9.0.11
  • nestjs-dynamoose 0.5.8
  • reflect-metadata 0.2.2
  • rimraf 5.0.5
  • rxjs 7.8.1
  • uuid 9.0.1
  • @commitlint/cli 19.2.2
  • @commitlint/config-conventional 19.2.2
  • @nestjs/cli 10.3.2
  • @nestjs/schematics 10.1.1
  • @nestjs/testing 10.3.7
  • @shelf/jest-dynamodb 3.4.4
  • @trivago/prettier-plugin-sort-imports 4.3.0
  • @types/aws-lambda 8.10.137
  • @types/express 4.17.21
  • @types/jest 29.5.12
  • @types/js-yaml 4.0.9
  • @types/node 20.12.7
  • @types/serverless 3.12.22
  • @types/supertest 6.0.2
  • @types/uuid 9.0.8
  • @typescript-eslint/eslint-plugin 7.7.0
  • @typescript-eslint/parser 7.7.0
  • change-case 5.4.4
  • cross-env 7.0.3
  • eslint 8.57.0
  • eslint-config-prettier 9.1.0
  • eslint-plugin-import 2.29.1
  • glob-promise 6.0.5
  • jest 29.7.0
  • js-yaml 4.1.0
  • lint-staged 15.2.2
  • prettier 3.2.5
  • serverless 3.38.0
  • serverless-dynamodb-local 0.2.40
  • serverless-offline 13.3.3
  • serverless-plugin-typescript 2.1.5
  • supertest 6.3.4
  • ts-jest 29.1.2
  • ts-loader 9.5.1
  • ts-node 10.9.2
  • tsconfig-paths 4.2.0
  • typescript 5.4.5

  • Check this box to trigger a request for Renovate to run again on this repository

How can i add websocket on this starter ?

Hi, I use this snippet and i want support websocket gateway.
I already configure my serverless.yml. when i request my socket endpoint I receive the data of my request in the variable event, but it does not forward it to my gateway.
How resolve this?

my handler

import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import { APIGatewayProxyHandler } from 'aws-lambda';
import { createServer, proxy } from 'aws-serverless-express';
import { eventContext } from 'aws-serverless-express/middleware';
import express from 'express';
import { Server } from 'http';
import { AppModule } from './app.module';

let cachedServer: Server;

const bootstrapServer = async (): Promise<Server> => {
  const expressApp = express();
  expressApp.use(eventContext());
  const app = await NestFactory.create(
    AppModule,
    new ExpressAdapter(expressApp),
  );
  app.useGlobalPipes(new ValidationPipe({ forbidUnknownValues: true }));
  app.enableCors();
  await app.init();
  return createServer(expressApp);
};

export const handler: APIGatewayProxyHandler = async (event, context) => {
  if (!cachedServer) {
    cachedServer = await bootstrapServer();
  }
  console.log('---event', event);
  // console.log('---context', context);
  
  return proxy(cachedServer, event, context, 'PROMISE').promise;
};

Why dont you use webpack?

More than an issue is a question ๐Ÿ˜ฌ . The official docs says that using webpack decrease the cold start time, because the bundle that is maded. Why dont you use it on this starter project?, is there a reason not to use it? ๐Ÿค” .

Besides that, thanks for the effort ๐Ÿ’ช

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.