1. Home
  2. Docs
  3. Engineering
  4. Serverless Functions

Serverless Functions

Serverless functions means deploying individual functions to a serverless function provider such as AWS Lambda. This is in contrast to deploying monolithic functions such as NestJS with Express/Fastify and serverless-express, which can still be deployed to AWS Lambda.

How to Create A TypeScript Serverless Functions Project

Install Serverless Framework CLI:

yarn global add serverless

The Serverless Functions project can contain multiple functions. For the project itself, Hendy recommends to use this format: {brand}-{noun}. By noun meaning not an active verb, for example, use “time-tracker” instead of “track-time”. Individual functions are usually named using active verbs. And by prefixing by brand name, it makes it easier to locate because we potentially will have hundreds or thousands of AWS Lambda functions.

mkdir talentiva-time-tracker
cd talentiva-time-tracker
serverless create -t aws-nodejs-typescript
yarn

This will create a TypeScript Serverless project with middy middleware framework, API Gateway proxying using REST (not HTTP) API type, Webpack build, and configured on us-east-1 region.

Add more rules using this gitignore.

Edit serverless.ts in this section to set :

  provider: {
    name: 'aws',
    region: 'ap-southeast-1',

@serverless/typescript vs serverless-plugin-typescript

@serverless/typescript is from Serverless Framework, so we are using this by default.

There serverless-plugin-typescript which is a contributed plugin that is more mature and works well with serverless-offline.

useDotenv: true

To make local testing more convenient, you will want to set useDotenv: true in serverless.ts:

  useDotenv: true,

Test A Function Locally

# Invoke local using mock data file (recommended)
yarn sls invoke local -f hello -p src/functions/hello/mock.json
# Invoke local using literal
yarn sls invoke local -f hello -d '{"body": {"name": "Hendy"}}'

Sample response:

{
    "statusCode": 200,
    "body": "{\"message\":\"Hello Hendy, welcome to the exciting Serverless world!\",\"event\":{\"body\":{\"name\":\"Hendy\"}}}"
}

Creating A New Function

You can either modify the code in src/functions/hello/handler.ts, or create your own handler. Here are the steps:

  1. Create a folder inside src/functions, Hendy recommends the naming to start with an active verb, and camelCase, e.g. reviewTimeLogs.
  2. Inside that folder you have 4 files:
    • handler.ts. The primary code.
    • index.ts. The mapping for Lambda trigger.
    • mock.json. Sample mock data for testing (warning: don’t put secrets here!).
    • schema.ts. JSON Schema for the input data. It is recommended so that your handler.ts can get type checking in VS Code. This is optional if you’re in a hurry, but then in handler.ts, use “any” instead of “typeof schema”.
  3. In serverless.ts, import your function and add it to serverlessConfiguration.functions section.
  4. In src/index.ts, export your function, for example: (Hendy thinks this is redundant)
    export { default as reviewTimeLogs } from './reviewTimeLogs';

handler.ts

import 'source-map-support/register';

import type { ValidatedEventAPIGatewayProxyEvent } from '@libs/apiGateway';
import { formatJSONResponse } from '@libs/apiGateway';
import { middyfy } from '@libs/lambda';

import schema from './schema';

const hello: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (event) => {
  return formatJSONResponse({
    message: `Hello ${event.body.name}, welcome to the exciting Serverless world!`,
    event,
  });
}

export const main = middyfy(hello);

index.ts

import schema from './schema';
import { handlerPath } from '@libs/handlerResolver';

export default {
  handler: `${handlerPath(__dirname)}/handler.main`,
  events: [
    {
      http: {
        method: 'post',
        path: 'hello',
        request: {
          schema: {
            'application/json': schema
          }
        }
      }
    }
  ]
}

mock.json

{
  "headers": {
    "Content-Type": "application/json"
  },
  "body": "{\"name\": \"Frederic\"}"
}

schema.ts

export default {
  type: "object",
  properties: {
    name: { type: 'string' }
  },
  required: ['name']
} as const;

Deploy All Functions

# Default is dev stage
serverless deploy -s dev
# production stage
serverless deploy -s production

Tail logs in production

yarn sls logs -s production -f reviewTimeLogs -t

Scheduling A Function using AWS EventBridge

Although it’s possible to schedule function using Serverless Framework, if you have complex/dynamic/multiple schedules, it’s better to use EventBridge either manually or via Pulumi IaaS.

Scheduling using EventBridge

For AWS EventBridge’s cron expression, an example if you want to schedule every working day at 17:30 WIB:
30 10 ? * MON-FRI *

Make sure to set Target -> Configure input, to the input needed by your serverless function. Don’t forget to wrap it with “body” field.

Get Deployment Configuration Information

yarn sls info -s dev
yarn sls info -s production
Was this article helpful to you? Yes No

How can we help?

Leave a Reply

Your email address will not be published. Required fields are marked *