A scalable, serverless AI chatbot backend built with AWS SAM, featuring hexagonal architecture for maintainability and portability.
This code is for demonstration purposes only and lacks the authorization and security measures required for a production MVP. Before deploying to production, implement at least:
- API authentication (API keys, JWT tokens, or AWS Cognito)
- Rate limiting and throttling
- Input validation and sanitization
- Proper IAM roles with least privilege
- Monitoring and logging for security events
- API Gateway: REST endpoint (
⚠️ No authentication in demo) - Lambda Function: Stateless chat orchestrator
- DynamoDB: Conversation history storage
- Amazon Bedrock: AI model integration (Claude 3 Haiku)
src/
├── app.py # Lambda handler (orchestrator)
├── core/
│ └── chat_service.py # Framework-agnostic business logic
├── adapters/
│ ├── database_adapter.py # DynamoDB operations
│ └── llm_adapter.py # Bedrock AI integration
└── requirements.txt
- AWS CLI configured with appropriate permissions
- AWS SAM CLI installed
- AWS Account with
anthropic.claude-3-haiku-20240307-v1:0model enabled in Amazon Bedrock. (If you prefer to use a different one make appropriate changes insrc/adapters/llm_adapter.py) - Python 3.11+
-
Build the application:
sam build
-
Deploy to AWS:
sam deploy --guided
-
Note the API endpoint URL from the deployment output.
POST /chat
{
"userId": "user123",
"message": "Hello, how are you?"
}{
"aiResponse": "Hello! I'm doing well, thank you for asking. How can I help you today?"
}- 400 Bad Request: Invalid input
- 500 Internal Server Error: System error
curl -X POST https://your-api-id.execute-api.region.amazonaws.com/Prod/chat \
-H "Content-Type: application/json" \
-d '{"userId": "test-user", "message": "Hello!"}'- Create a new POST request
- Set URL to your API endpoint +
/chat - Set Content-Type header to
application/json - Add request body with
userIdandmessage
- Warm Initialization: AWS SDK clients initialized outside handler
- Efficient Queries: DynamoDB queries limited to recent messages
- Stateless Design: No memory state between invocations
For high-traffic scenarios, consider:
- Enabling Provisioned Concurrency in
template.yaml - Implementing DynamoDB auto-scaling
- Adding CloudWatch monitoring and alarms
An example web interface is available in the frontend/ directory:
- Deploy backend first (see Deployment section above)
- Update API endpoint in
frontend/script.js - Serve locally:
cd frontend python -m http.server 8000 - Open: http://localhost:8000
To remove all resources:
sam delete