Project Structure
Understanding how Serverless Monolith discovers and organizes your modules.
Recommended Structure
your-project/
├── src/
│ └── modules/ # Modules directory (configurable)
│ ├── user/ # Module: user
│ │ ├── functions.yml # Function definitions
│ │ └── handlers/ # Handler implementations
│ │ ├── create/
│ │ │ └── index.ts
│ │ └── list/
│ │ └── index.ts
│ ├── order/ # Module: order
│ │ ├── functions.yml
│ │ └── handlers/
│ │ └── ...
│ └── notification/ # Module: notification
│ ├── functions.yml
│ └── handlers/
│ └── ...
├── monolith.config.ts # Configuration file
├── package.json
└── tsconfig.json
Module Discovery
Serverless Monolith automatically discovers modules based on the presence of a functions.yml file. Each directory containing this file is treated as a module.
Discovery Configuration
// monolith.config.ts
export default {
discovery: {
modulesDir: 'src/modules', // Where to look for modules
functionsFile: 'functions.yml', // Name of function definition file
strategy: 'explicit', // Discovery strategy
},
};
Discovery Strategies
| Strategy | Description |
|---|---|
explicit | Only discover modules with functions.yml |
recursive | Recursively search for functions.yml in subdirectories |
Functions File Format
The functions.yml file defines your serverless functions:
# HTTP Function
createUser:
handler: handlers/create/index.handler
events:
- http:
path: users
method: POST
cors: true
# SQS Function
processOrder:
handler: handlers/process/index.handler
events:
- sqs:
arn:
Fn::GetAtt: [ProcessOrderQueue, Arn]
batchSize: 10
Handler Structure
Each handler is a TypeScript/JavaScript file exporting a function:
// handlers/create/index.ts
import { APIGatewayProxyHandler } from 'aws-lambda';
export const handler: APIGatewayProxyHandler = async (event, context) => {
// Your logic here
return {
statusCode: 200,
body: JSON.stringify({ success: true }),
};
};
Environment Variables
Create a .env file in your project root:
# .env
DATABASE_URL=postgresql://localhost:5432/mydb
AWS_REGION=us-east-1
LOG_LEVEL=debug
Serverless Monolith automatically loads these variables before executing handlers.
TypeScript Configuration
Recommended tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"]
}
Multiple Projects
For monorepo setups with multiple serverless projects, use the Proxy package:
monorepo/
├── services/
│ ├── api-users/
│ │ └── src/modules/...
│ ├── api-orders/
│ │ └── src/modules/...
│ └── api-payments/
│ └── src/modules/...
├── proxy.config.ts
└── lighthouse.config.ts
See the Proxy documentation for multi-service routing.