My little corner of the internet showcasing personal projects and updates about my work
API Tech Design Doc
Overview
Fusite API is a serverless Express API that serves my projects' metadata from a Notion DB. Deployed on AWS Lambda with API Gateway, it provides read-only access to project portfolios, development chronicles, and documentation—all managed through Notion's collaborative interface.
This approach combines the developer experience of a traditional database with the content editing simplicity of Notion.
This API is used by the Fuscapp Hub to list my current available projects.
Core Architecture
Serverless Express Pattern
Client Request
↓
API Gateway (HTTP API)
↓
AWS Lambda (Node.js 22)
↓
serverless-http adapter
↓
Express Application
├── CORS Middleware
├── Health Check
└── Project Controller
↓
NotionService (fusite-commons)
↓
Notion APIKey Technology Choices:
The architecture follows a thin API gateway pattern—Express handles HTTP semantics while Lambda provides compute. This separation enables horizontal scaling without server management.
The Notion-as-Database Pattern
Why Notion?
Traditional CMSs require admin panels, migrations, and complex schemas. Notion provides:
Type System & Contracts
Domain Models
The system defines comprehensive TypeScript interfaces in fusite-commons:
Project:
interface Project {
id: string
title: string
slug: string
status:
| "planning"
| "in-progress"
| "active"
| "completed"
| "on-hold"
| "cancelled"
technologies: string[]
technologyColors: { name: string; color?: string }[]
description?: string
repositoryUrl?: string
liveUrl?: string
featuredImage?: { url: string; alt: string }
dates: { start?: string; end?: string }
content?: HtmlContent[] // Notion blocks converted to HTML
}Fuschronicle (Development Logs):
interface Fuschronicle {
id: string
title: string
slug: string
type:
| "project-update"
| "milestone"
| "learning"
| "retrospective"
| "technical"
| "general"
| "documentation"
| "changelog"
publishedDate?: string
excerpt?: string
relatedProject?: Array<{ id: string; title: string; slug: string }>
content: HtmlContent[]
}HtmlContent (Pre-rendered Notion Blocks):
interface HtmlContent {
type: "heading_1" | "heading_2" | "paragraph" | "code" | "image" |
"bulleted_list" | "numbered_list" | ... // 25+ types
html: string // Pre-processed HTML
content?: string
language?: string // For code blocks
annotations?: {
bold?: boolean
italic?: boolean
code?: boolean
color?: string
}
href?: string
src?: string
}This rich type system ensures:
Deployment Architecture
Serverless Framework Configuration
provider:
name: aws
runtime: nodejs22.x
httpApi:
id: ${env:API_GATEWAY_ID}
disableDefaultEndpoint: true # Custom domain only
logRetentionInDays: 90
logs:
lambda:
logFormat: JSON # Structured logging for CloudWatch
functions:
express-handler:
handler: src/lambdaHandler.handler
events:
- httpApi: /fusite
- httpApi: /fusite/{proxy+}Key Decisions:
Infrastructure-as-Code Benefits
serverless deploy recreates entire stackKey Design Decisions
1. Notion Over Traditional Database
Rationale:
Trade-offs:
2. Shared fusite-commons Library
Rationale:
Implementation:
file:../commons dependencytsc in commons builds to dist/)3. Serverless Express Instead of Pure Lambda
Rationale:
bun run dev (no AWS emulation)Trade-offs:
4. Read-Only Public API
Rationale:
Future Extensions:
Performance Characteristics
API Response Times
Typical Metrics (measured from CloudWatch):
Optimization Strategies:
Promise.all()Scaling Characteristics
Lambda Auto-Scaling:
API Gateway:
Technical Highlights
Architectural Patterns Demonstrated
| Pattern | Implementation | Benefit |
| Service Layer | NotionService abstracts external API | Testable, reusable, maintainable |
| Repository Pattern | Controllers delegate to services | Decoupled from data source |
| Response Envelope | Consistent { success, data, error } | Predictable client handling |
| Lazy Loading | AWS SDK imported conditionally | Reduced bundle size |
| Environment Segregation | BUILD_ENV-aware logic | Production safety |
| Error Adapter | Notion errors → user messages | Better debugging UX |
Technology Proficiencies Showcased
Summary
Fusite API demonstrates that unconventional data stores can enable elegant architectures. By leveraging Notion as a database, the system achieves:
The architecture proves that modern APIs don't require traditional databases—thoughtful abstraction layers can turn collaborative tools into first-class data stores while maintaining professional standards for type safety, testing, and deployment.