Module Discovery
Learn how Serverless Monolith discovers and loads your modules.
How Discovery Works
Serverless Monolith automatically discovers modules based on the presence of a functions.yml file. Each directory containing this file is treated as a module.
src/modules/
├── user/ # Module: user
│ ├── functions.yml # ✓ Discovered
│ └── handlers/
├── order/ # Module: order
│ ├── functions.yml # ✓ Discovered
│ └── handlers/
└── shared/ # Not a module
└── utils.ts # ✗ No functions.yml
Discovery Strategies
Explicit Strategy (Default)
Only directories directly under modulesDir with functions.yml are discovered:
{
discovery: {
modulesDir: 'src/modules',
strategy: 'explicit'
}
}
Recursive Strategy
Searches recursively for functions.yml in subdirectories:
{
discovery: {
modulesDir: 'src',
strategy: 'recursive'
}
}
This allows nested module structures:
src/
├── domains/
│ ├── user/
│ │ └── functions.yml # ✓ Discovered
│ └── order/
│ └── functions.yml # ✓ Discovered
└── shared/
└── utils.ts # ✗ Ignored
Functions File Format
The functions.yml file defines your serverless functions:
# HTTP Functions
createUser:
handler: handlers/create/index.handler
events:
- http:
path: users
method: POST
cors: true
listUsers:
handler: handlers/list/index.handler
events:
- http:
path: users
method: GET
cors: true
getUserById:
handler: handlers/get/index.handler
events:
- http:
path: users/{id}
method: GET
# SQS Functions
processUserQueue:
handler: handlers/process/index.handler
events:
- sqs:
arn:
Fn::GetAtt: [ProcessUserQueue, Arn]
batchSize: 10
Handler Resolution
Handlers are resolved relative to the module directory:
src/modules/user/
├── functions.yml
└── handlers/
└── create/
└── index.ts # handler: handlers/create/index.handler
The handler path handlers/create/index.handler resolves to:
- File:
src/modules/user/handlers/create/index.ts - Export:
handler
Path Parameters
Path parameters are defined using curly braces:
getUserById:
handler: handlers/get/index.handler
events:
- http:
path: users/{id}
method: GET
updateUserAddress:
handler: handlers/address/index.handler
events:
- http:
path: users/{userId}/addresses/{addressId}
method: PUT
These are available in the handler via event.pathParameters:
export const handler: APIGatewayProxyHandler = async (event) => {
const { id } = event.pathParameters || {};
// ...
};
Security Validations
The discovery system includes security validations:
- Path Traversal Prevention: Handler paths cannot escape the module directory
- File Existence Check: Warns if handler files don't exist
- Export Validation: Validates that the specified export exists
Debugging Discovery
Enable discovery logging to debug issues:
{
logging: {
enabledCategories: ['moduleDiscovery'],
showRoutesTable: true
}
}
This will show:
[discovery] Scanning directory: src/modules
[discovery] Found module: user (3 functions)
[discovery] Found module: order (5 functions)
[discovery] Total: 2 modules, 8 functions
Next Steps
- HTTP Handlers - Creating HTTP handlers
- SQS Handlers - Working with queues