7.2 KiB
Elysia API Documentation
Overview
This project uses ElysiaJS integrated with Next.js App Router to create high-performance, type-safe APIs. The codebase follows a Feature-based MVC pattern for maintainability and scalability.
Base URL
http://localhost:3001
Endpoints
Customers API
Get All Customers by Branch
GET /api/customers/:branch
Parameters:
branch(path parameter, required): Branch identifier- Examples:
branch-01,branch-02,head-office
- Examples:
status(query parameter, optional): Filter by customer status- Values:
active,inactive,pending
- Values:
Examples:
- Get all customers from branch-01:
curl http://localhost:3001/api/customers/branch-01
- Get active customers from branch-02:
curl "http://localhost:3001/api/customers/branch-02?status=active"
- Get pending customers from head-office:
curl "http://localhost:3001/api/customers/head-office?status=pending"
Response Format:
{
"success": true,
"data": [
{
"id": "cust-001",
"branch": "branch-01",
"name": "สมชาย ใจดี",
"email": "somchai@example.com",
"phone": "081-234-5678",
"company": "บริษัท ไทยธุรกิจ จำกัด",
"address": "123 ถนนสุขุมวิท แขวงคลองตัน เขตคลองเตย กรุงเทพฯ 10110",
"status": "active",
"createdAt": "2024-01-15T09:00:00Z",
"updatedAt": "2024-01-15T09:00:00Z"
}
],
"count": 1,
"message": "Found 1 customer(s) for branch: branch-01"
}
Get Single Customer by ID
GET /api/customers/:branch/:id
Create Customer
POST /api/customers
Update Customer
PUT /api/customers/:branch/:id
Delete Customer
DELETE /api/customers/:branch/:id
Quotations API
Get All Quotations by Branch
GET /api/quotations/:branch
Parameters:
branch(path parameter, required): Branch identifier- Examples:
branch-01,branch-02,head-office
- Examples:
status(query parameter, optional): Filter by quotation status- Values:
draft,sent,accepted,rejected,expired
- Values:
Examples:
- Get all quotations from branch-01:
curl http://localhost:3001/api/quotations/branch-01
- Get sent quotations from head-office:
curl "http://localhost:3001/api/quotations/head-office?status=sent"
Response Format:
{
"success": true,
"data": [
{
"id": "quot-001",
"quotationNumber": "QT-2024-001",
"branch": "branch-01",
"customerId": "cust-001",
"customerName": "สมชาย ใจดี",
"date": "2024-01-20T00:00:00Z",
"validUntil": "2024-02-20T00:00:00Z",
"subtotal": 50000,
"taxRate": 0.07,
"taxAmount": 3500,
"totalAmount": 53500,
"status": "sent",
"notes": "Quotation for office supplies",
"createdAt": "2024-01-20T09:00:00Z",
"updatedAt": "2024-01-20T09:00:00Z"
}
],
"count": 2,
"message": "Found 2 quotation(s) for branch: branch-01"
}
Get Single Quotation by ID
GET /api/quotations/:branch/:id
Create Quotation
POST /api/quotations
Update Quotation
PUT /api/quotations/:branch/:id
Delete Quotation
DELETE /api/quotations/:branch/:id
Available Data
Customers
branch-01: 4 customers (3 active, 1 pending)branch-02: 3 customers (1 active, 1 inactive, 1 pending)head-office: 3 customers (all active)
Quotations
branch-01: 2 quotations (1 sent, 1 accepted)branch-02: 1 quotation (draft)head-office: 1 quotation (sent)
Testing with Browser
Simply open these URLs in your browser:
Customers
- http://localhost:3001/api/customers/branch-01
- http://localhost:3001/api/customers/branch-02?status=active
- http://localhost:3001/api/customers/head-office
Quotations
- http://localhost:3001/api/quotations/branch-01
- http://localhost:3001/api/quotations/head-office?status=sent
Project Structure
This project follows the Feature-based MVC pattern as recommended by ElysiaJS:
src/
├── app/
│ └── api/
│ └── [[...slugs]]/
│ └── route.ts # Main API entry point
├── modules/
│ ├── customers/
│ │ ├── controller.ts # HTTP handlers & routing
│ │ ├── service.ts # Business logic
│ │ └── model.ts # Schemas & validation
│ └── quotations/
│ ├── controller.ts # HTTP handlers & routing
│ ├── service.ts # Business logic
│ └── model.ts # Schemas & validation
├── types/
│ └── customer.ts # Shared types
├── lib/
│ └── mock-data.ts # Mock data
File Responsibilities
Model (model.ts)
- Define TypeBox schemas for validation
- Export TypeScript types from schemas
- All data structure definitions
Service (service.ts)
- Business logic and data operations
- Pure functions (no Elysia dependencies)
- CRUD operations
- Data transformation
Controller (controller.ts)
- Elysia instance for the module
- Route definitions and handlers
- Request/response validation
- Calls service functions
- HTTP-specific concerns
Main Route (app/api/[[...slugs]]/route.ts)
- Import all controllers
- Combine with
.use() - Export handlers for Next.js
Important Implementation Notes
This project follows the correct ElysiaJS + Next.js integration pattern:
- ✅ Single route file
[[...slugs]]/route.tswith Elysia internal routing - ✅ Uses
export const GET = app.fetch(not.handle) - ✅ Elysia instance has
prefix: '/api' - ✅ All routes defined within Elysia instances using
.get(),.post(), etc. - ✅ WinterCG compliant - works as normal Next.js API route
- ✅ Feature-based MVC pattern for maintainability
- ✅ Clear separation of concerns between Model, View, and Controller
Technologies Used
- ElysiaJS: Type-safe, high-performance web framework
- Next.js 16: React framework with App Router
- TypeScript: Type safety throughout
- TypeBox: Schema validation (via
@elysiajs/schema)
Features
✅ Feature-based MVC architecture
✅ Dynamic branch parameter support
✅ Type-safe request/response validation
✅ Optional query parameter filtering
✅ Mock data for customers and quotations
✅ Full TypeScript support
✅ Auto-generated API documentation (Swagger/OpenAPI ready)
✅ Correct ElysiaJS + Next.js integration pattern
✅ Scalable and maintainable code structure
✅ Clear separation of concerns
Adding New Modules
To add a new module (e.g., products):
-
Create folder:
src/modules/products/ -
Create
model.ts- Define schemas -
Create
service.ts- Business logic -
Create
controller.ts- Routes and handlers -
Update
src/app/api/[[...slugs]]/route.ts:import { products } from "@/modules/products/controller"; const app = new Elysia({ prefix: "/api" }) .use(customers) .use(quotations) .use(products); // Add new module