Atul
Atul

Reputation: 1590

AWS SAM Deployment Configuration Issue

I have set up a simple serverless rest api using Node JS and AWS Lambda.

The deployment is done using AWS SAM

Below is the SAM Template :

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: Serverless API With SAM

Resources:
  createUser:
    Type: AWS::Serverless::Function
    Properties:
      Handler: handler.create
      MemorySize: 128
      Runtime: nodejs12.x
      Timeout: 3
      Events:
        createUserApi:
          Type: Api
          Properties : 
              Path : /users
              Method : post
  
  listUsers:
     Type: AWS::Serverless::Function
     Properties:
      Handler: handler.list
      MemorySize: 128
      Runtime: nodejs12.x
      Timeout: 3
      Events:
        listUserApi:
          Type: Api
          Properties : 
              Path : /users
              Method : get

This works fine but below is my observation regarding stacks created. It creates two AWS Lambda functions instead of one.

Both contain two APIs listed as -

createUser
listUsers

Can it not contain only on Lambda function with these two handlers inside ?

handler.js file :

const connectedToDb = require('./src/db/db.js');
const User = require('./src/model/user.js');

module.exports.create = async (event,context) =>{

   console.log('create function called !!');

   try{
    console.log('before connecting to DB ');   
    await connectedToDb();
    console.log('after connecting to DB ');   
    const usr = new User(JSON.parse(event.body));
    console.log('saving a user now  with ',event.body);   
    await usr.save();
    return{
        statusCode : 200,
        body:JSON.stringify(usr)
    }

   }catch(err){
        return{
            statusCode : err.statusCode || 500,
            body : 'Cannot Create Order'
        }
   }
}

module.exports.list = async (event,context) => {

    console.log('listing all users');
    try{
        await connectedToDb();
        const users = await User.find({});
        console.log('users are == ',users);
        return {
            statusCode:200,
            body:JSON.stringify(users)
        }

    }catch(err){

        return {
            statusCode:err || 500,
            body:JSON.stringify(err)
        }
    }
}

Upvotes: 0

Views: 71

Answers (1)

Dylan Koster
Dylan Koster

Reputation: 3

Every AWS::Serverless:Function defined in template.yaml creates a new lambda function. If you want to create just one function that handles the /users endpoint you can do something like this:

template.yaml:

AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: Serverless API With SAM

Resources:
  user:
    Type: AWS::Serverless::Function
    Properties:
      Handler: handler.lambda_handler
      MemorySize: 128
      Runtime: nodejs16.x
      Timeout: 3
      Events:
        createUserApi:
          Type: Api
          Properties:
            Path: /users
            Method: post
        listUserApi:
          Type: Api
          Properties:
            Path: /users
            Method: get

handler.js:

create = async (event, context) => {
  // Do whatever
  return { statusCode: 200, body: "create() called!" };
};

list = async (event, context) => {
  // Do whatever

  return { statusCode: 200, body: "list() called!" };
};

module.exports.lambda_handler = async (event, context) => {
  if (event["httpMethod"] == "GET") {
    return list(event, context);
  } else if (event["httpMethod"] == "POST") {
    return create(event, context);
  } else {
    // This shouldn't happen.
    return { statusCode: 400, body: "Method not supported." };
  }
};

This way both the GET and the POST methods redirect to the lambda_handler function, which then can ditribute the work based on the actualy HTTP method.

Upvotes: 0

Related Questions