Is there a way to call a serverless function locally and provide parameters through the `body` attribute? How can

I am currently experimenting with testing a lambda function locally using the serverless framework. This particular function is connected to a POST endpoint, which is defined as:

createCat:
  handler: app/handler.createCat
  events:
    - http:
        path: cats/
        method: post

To invoke this function locally, I followed the steps outlined in this source:

# Command line
serverless invoke local --function createCat --path local-invoke/createCat.json --stage local

# createCat.json
{
  "body": {
    "name": "Cat cat blue",
    "age": 4,
    "color": "blue"
  }
}

In an attempt to parse the body and retrieve its contents as shown here, I implemented the following code snippet:

import { Context } from 'aws-lambda';

const createCat = async (event: any, context?: Context) => {
  try{
  const data  = JSON.parse(event.body)

  let name = data?.name
  let age = Number(data?.age)
  let color = data?.color

  return {
    statusCode: 500,
    message: data
  }
  }
  catch(error) {
  return {
    statusCode: 500,
    body: JSON.stringify({
      message: getMessageFromError(error)
    })
  }
  } 
}

However, instead of obtaining the parsed body, I am receiving the following output:

{
    "statusCode": 500,
    "body": "{\"message\":\"Unexpected token l in JSON at position 0\"}"
}

The Serverless documentation on local invoke does not provide guidance on how to pass or retrieve body parameters either.

Where could I be going wrong in this process?

Answer №1

When calling the deployed lambda function, the event.body is a JSON string that needs to be escaped. However, when calling it locally with serverless invoke local, it becomes an object literal in JavaScript, causing a parsing error because it tries to parse this object literal.

To handle both cases seamlessly, I created a helper function:

// types.ts
export interface ParsedEvent {
  body: any | undefined,
  pathParameters: any | undefined
}

// util.ts
import { ParsedEvent } from "./types"

export const parseEvent = (event: any) : ParsedEvent => {
  let parsedEvent : ParsedEvent = {
    body: undefined,
    pathParameters: undefined
  }

  parsedEvent.pathParameters = event?.pathParameters

  // Parse body if it is stringified JSON
  if(typeof event?.body === 'string' )
  {   
    parsedEvent.body = JSON.parse(event?.body)
  } else {
    parsedEvent.body = event?.body
  }

  return parsedEvent
}

and you can use it like this:

import { Context } from 'aws-lambda';
import { parseEvent } from './util.js';

const createCat = async (event: any, context?: Context) => {
  let parsedEvent = parseEvent(event)
  
  // body parameters
  let name = parsedEvent.body?.name
  let age = parsedEvent.body?.age
  
  // path parameters
  let id = parsedEvent.pathParameters?.id
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble setting up Typescript in VisualStudio 2015 due to the error message "exports is not defined"? Need guidance on the correct setup?

I am new to TypeScript and I am currently learning about exports and imports in TypeScript However, as I started working on it, I encountered an error with exports Object.defineProperty(exports, "__esModule", { value: true }); The error message I receiv ...

A comprehensive approach to comparing subsets within a set

I'm curious about implementing an exhaustive switch/case using the "never" type. Imagine I have a Set of strings: {A, B} (these strings can be long and the Set can be large). For each subset (like {}, {A,B}), I want to create a function called show: ...

MUI Select component not displaying top border

Can anyone help me understand why the select field is behaving this way? I'm new to the project and suspect that someone may have made changes to it. https://i.sstatic.net/pB6Sx.png <mui.FormControl style={{ width: '598px' }}> ...

How to alter the HTML view in Angular 2 after it has been processed

Here is some Angular 2 code snippet: import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: 'Waiting on port ', }) export class AppComponent { } I want to dynamically add the text "3000" ...

Alert: Using Angularfire SDK could result in console log issues

I've been encountering this persistent warning that I just can't seem to get rid of no matter what I try. Here are the versions I'm using: angular 11.0.1 @angular/fire 6.1.3 firebase 7.0.0 || 8.0.0 https://i.sstatic.net/5Tyt5.png ...

Error in TypeScript when accessing object using string variable as index

Currently, I am facing a challenge in my project where I am dynamically generating routes and managing them in an Elysia(~Express) application. The issue arises when TypeScript's type checking system fails to index an object using a string variable. S ...

Can you explain the concept of interface with dual function type declarations and provide guidance on its implementation?

interface MyInterface { (choose: string): number; (item: number): string; } Can you provide guidance on using the MyInterface interface mentioned above? How would it be helpful in practical situations? ...

How can one determine if a background image has successfully loaded in an Angular application?

In my Angular 7 application, I am displaying a background image in a div. However, there are instances when the link to the image is broken. The way I bind the image in my HTML is as follows: <div [ngStyle]="{'background-image': 'url(&a ...

The performance of web API calls on an Angular 7 app deteriorates gradually with each subsequent call

My Angular application in C# is experiencing a slowdown when making calls to the web API and executing a stored procedure. While the C# code performs quickly, the 'Content Download' process is progressively slowing down with each call. https://i ...

What is the reason for polyfilling private fields (#field) in JavaScript on angular builds?

I was eager to incorporate JavaScript private fields into my Angular (v17) application built with Angular CLI. I specified the target as ES2022 in the tsconfig, but after building the app, I discovered that my private field had been poly-filled with a We ...

Mastering the Use of Interfaces in Ionic/Angular

My journey into angular/ionic app development is just beginning. I came across the following piece of advice recently Interfaces are only at compile time. This allows only you to check that the expected data received follows a particular structure. Curre ...

The most secure method for retrieving User Id in AngularFire2

I'm currently facing a dilemma in determining the most secure method to obtain an authenticated user's uid using AngularFire2. There seem to be two viable approaches available, but I am uncertain about which one offers the best security measures ...

What happens when I include *ngIf = "authService.getUser()" in the root component html of my application that causes issues with my login component?

As a newcomer to Angular, I admit my lack of experience. I recently created a login component for the purpose of restricting access to router navigation links in the main app-component HTML until the user successfully logs in. Originally, the login compone ...

Encountering difficulty locating <arg" while providing argument to redux-saga using typescript

My takeLatest() saga function is calling postDeliverySubmitSaga(), and I need to pass arguments to it. This is how I'm defining my functions: export function* postDeliverySubmitSaga({ payload: any }: ReturnType<typeof setDeliverySubmit>) { ...

Caution in NEXTJS: Make sure the server HTML includes a corresponding <div> within a <div> tag

Struggling with a warning while rendering pages in my Next.js and MUI project. Here's the code, any insights on how to resolve this would be greatly appreciated! import "../styles/globals.scss"; import { AppProps } from "next/app"; ...

Enhancements to a NativeScript Application

After running some tests on my NativeScript app following the steps outlined here - , I found that it takes 18 seconds for the program to start and for a user to log in. Is this considered acceptable performance? Appreciate any feedback provided! ...

Dynamic Setting of Content-Type Header (Multipart/Data) Through Http Interceptor

I have been trying to upload a CSV file using an HttpInterceptor as a middleware. Everything works fine for normal requests, but I need to modify the request header to 'multipart/data' specifically for CSV uploads. Below is the code snippet: ex ...

Leveraging symbols as object key type in TypeScript

I am attempting to create an object with a symbol as the key type, following MDN's guidance: A symbol value may be used as an identifier for object properties [...] However, when trying to use it as the key property type: type obj = { [key: s ...

Designing a TypeScript class with unique properties and attributes

I have an idea for creating a versatile class named Model. Here's what I have in mind: export class Model { _required_fields: Array<string> = []; _optional_fields?: Array<string> = []; constructor(params: Dictionary<string& ...

Symfony Encore does not generate the index.html file during the build process

I have been utilizing a free website hosting service for my domain. The original source code on GitHub utilizes Symfony to construct the project. "scripts": { "dev-server": "encore dev-server", "dev": " ...