Deno Fresh Backend API โ
HaloLight Deno backend API is built on Fresh framework and Deno KV, using the native Deno runtime to provide high-performance RESTful API services.
API Documentation: https://halolight-deno.h7ml.cn/docs
GitHub: https://github.com/halolight/halolight-deno
Features โ
- ๐ JWT Dual Tokens - Access Token + Refresh Token with auto-renewal
- ๐ก๏ธ RBAC Permissions - Role-based access control with wildcard matching
- ๐ก RESTful API - Standardized interface design with OpenAPI documentation
- ๐พ Deno KV - Built-in key-value storage, no external database needed
- โก Islands Architecture - Partial hydration for extreme performance
- โ Data Validation - Request parameter validation and error handling
- ๐ Logging System - Request logs and error tracking
- ๐ณ Docker Support - Containerized deployment
Tech Stack โ
| Technology | Version | Description |
|---|---|---|
| Deno | 2.x | Runtime (built-in TypeScript) |
| Fresh | 1.x | Deno-native web framework |
| Preact | 10.x | Lightweight UI library |
| Deno KV | - | Built-in key-value storage (database) |
| Hono | 4.x | API routing framework (optional) |
| JWT | - | Authentication |
| Tailwind CSS | 3.x | Atomic CSS |
Quick Start โ
Requirements โ
- Deno >= 2.0.0
Installation โ
bash
# Clone repository
git clone https://github.com/halolight/halolight-deno.git
cd halolight-deno
# No dependency install needed, Deno manages automaticallyEnvironment Variables โ
bash
cp .env.example .envenv
# API Configuration
API_URL=/api
USE_MOCK=true
# JWT Secret
JWT_SECRET=your-super-secret-key
JWT_ACCESS_EXPIRES=15m
JWT_REFRESH_EXPIRES=7d
# Deno KV (optional, local by default)
DENO_KV_PATH=./data/kv.db
# Service Configuration
PORT=8000
NODE_ENV=development
# Demo Account
DEMO_EMAIL=admin@halolight.h7ml.cn
DEMO_PASSWORD=123456
SHOW_DEMO_HINT=false
# Brand Configuration
APP_TITLE=Admin Pro
BRAND_NAME=HalolightDatabase Initialization โ
bash
# Deno KV requires no migration, auto-creates
# If seed data needed
deno task seedStart Service โ
bash
# Development mode
deno task dev
# Production mode
deno task build
deno task startVisit http://localhost:8000
Project Structure โ
halolight-deno/
โโโ routes/ # Route handlers
โ โโโ api/ # API endpoints
โ โ โโโ auth/ # Auth routes
โ โ โโโ users/ # User routes
โ โ โโโ dashboard/ # Dashboard routes
โ โ โโโ documents/ # Document routes
โ โ โโโ files/ # File routes
โ โ โโโ messages/ # Message routes
โ โ โโโ notifications/ # Notification routes
โ โ โโโ calendar/ # Calendar routes
โ โโโ (auth)/ # Auth pages
โ โ โโโ login.tsx
โ โ โโโ register.tsx
โ โ โโโ forgot-password.tsx
โ โโโ (dashboard)/ # Dashboard pages
โ โโโ index.tsx
โ โโโ users.tsx
โ โโโ settings.tsx
โโโ utils/ # Utilities
โ โโโ auth.ts # Auth utilities
โ โโโ kv.ts # Deno KV wrapper
โ โโโ permissions.ts # Permission checks
โ โโโ jwt.ts # JWT utilities
โ โโโ validation.ts # Data validation
โโโ islands/ # Interactive components (client-side)
โ โโโ AuthProvider.tsx
โ โโโ ThemeToggle.tsx
โ โโโ Dashboard.tsx
โโโ components/ # UI components
โ โโโ ui/
โ โโโ layout/
โ โโโ dashboard/
โโโ static/ # Static assets
โโโ fresh.gen.ts # Fresh generated file
โโโ fresh.config.ts # Fresh config
โโโ deno.json # Deno config
โโโ import_map.json # Import mapAPI Modules โ
Authentication Endpoints โ
| Method | Path | Description | Permission |
|---|---|---|---|
| POST | /api/auth/login | User login | Public |
| POST | /api/auth/register | User registration | Public |
| POST | /api/auth/refresh | Refresh token | Public |
| POST | /api/auth/logout | User logout | Authenticated |
| POST | /api/auth/forgot-password | Forgot password | Public |
| POST | /api/auth/reset-password | Reset password | Public |
User Management Endpoints โ
| Method | Path | Description | Permission |
|---|---|---|---|
| GET | /api/users | Get user list | users:view |
| GET | /api/users/:id | Get user details | users:view |
| POST | /api/users | Create user | users:create |
| PUT | /api/users/:id | Update user | users:update |
| DELETE | /api/users/:id | Delete user | users:delete |
| GET | /api/users/me | Get current user | Authenticated |
Complete Endpoint List โ
Document Management (Documents) - 5 endpoints โ
| Method | Path | Description |
|---|---|---|
| GET | /api/documents | Get document list |
| GET | /api/documents/:id | Get document details |
| POST | /api/documents | Create document |
| PUT | /api/documents/:id | Update document |
| DELETE | /api/documents/:id | Delete document |
File Management (Files) - 5 endpoints โ
| Method | Path | Description |
|---|---|---|
| GET | /api/files | Get file list |
| GET | /api/files/:id | Get file details |
| POST | /api/files/upload | Upload file |
| PUT | /api/files/:id | Update file info |
| DELETE | /api/files/:id | Delete file |
Message Management (Messages) - 5 endpoints โ
| Method | Path | Description |
|---|---|---|
| GET | /api/messages | Get message list |
| GET | /api/messages/:id | Get message details |
| POST | /api/messages | Send message |
| PUT | /api/messages/:id/read | Mark as read |
| DELETE | /api/messages/:id | Delete message |
Notification Management (Notifications) - 4 endpoints โ
| Method | Path | Description |
|---|---|---|
| GET | /api/notifications | Get notification list |
| PUT | /api/notifications/:id/read | Mark as read |
| PUT | /api/notifications/read-all | Mark all as read |
| DELETE | /api/notifications/:id | Delete notification |
Calendar Management (Calendar) - 5 endpoints โ
| Method | Path | Description |
|---|---|---|
| GET | /api/calendar/events | Get event list |
| GET | /api/calendar/events/:id | Get event details |
| POST | /api/calendar/events | Create event |
| PUT | /api/calendar/events/:id | Update event |
| DELETE | /api/calendar/events/:id | Delete event |
Dashboard - 6 endpoints โ
| Method | Path | Description |
|---|---|---|
| GET | /api/dashboard/stats | Statistics data |
| GET | /api/dashboard/visits | Visit trends |
| GET | /api/dashboard/sales | Sales data |
| GET | /api/dashboard/pie | Pie chart data |
| GET | /api/dashboard/tasks | Todo tasks |
| GET | /api/dashboard/calendar | Today's schedule |
Authentication โ
JWT Dual Tokens โ
Access Token: 15-minute validity for API requests
Refresh Token: 7-day validity for refreshing Access TokenRequest Headers โ
http
Authorization: Bearer <access_token>Refresh Flow โ
typescript
// utils/jwt.ts
import { create, verify } from "https://deno.land/x/djwt@v3.0.0/mod.ts";
const key = await crypto.subtle.generateKey(
{ name: "HMAC", hash: "SHA-256" },
true,
["sign", "verify"],
);
export async function createAccessToken(userId: string): Promise<string> {
return await create(
{ alg: "HS256", typ: "JWT" },
{ userId, exp: Date.now() + 15 * 60 * 1000 }, // 15 minutes
key,
);
}
export async function refreshToken(refreshToken: string): Promise<string> {
const payload = await verify(refreshToken, key);
return await createAccessToken(payload.userId as string);
}Permission System โ
Role Definitions โ
| Role | Description | Permissions |
|---|---|---|
super_admin | Super Administrator | * (all permissions) |
admin | Administrator | users:*, documents:*, files:*, messages:*, calendar:* |
user | Regular User | documents:view, files:view, messages:view, calendar:view |
guest | Guest | dashboard:view |
Permission Format โ
{resource}:{action}
Examples:
- users:view # View users
- users:create # Create users
- users:* # All user operations
- * # All permissionsPermission Check Implementation โ
typescript
// utils/permissions.ts
export function hasPermission(user: User, permission: string): boolean {
const userPermissions = user.permissions || [];
return userPermissions.some((p) => {
if (p === "*") return true;
if (p.endsWith(":*")) {
const resource = p.slice(0, -2);
return permission.startsWith(resource + ":");
}
return p === permission;
});
}
// Route middleware
export function requirePermission(permission: string) {
return async (req: Request, ctx: any) => {
const user = ctx.state.user;
if (!hasPermission(user, permission)) {
return new Response("Forbidden", { status: 403 });
}
return await ctx.next();
};
}Error Handling โ
Error Response Format โ
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request parameter validation failed",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
}Error Codes โ
| Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Parameter validation failed |
| 401 | UNAUTHORIZED | Unauthorized |
| 403 | FORBIDDEN | Forbidden |
| 404 | NOT_FOUND | Resource not found |
| 409 | CONFLICT | Resource conflict |
| 500 | INTERNAL_ERROR | Server error |
Common Commands โ
bash
# Development
deno task dev # Start dev server (hot reload)
# Build
deno task build # Build production bundle
# Testing
deno test # Run tests
deno test --coverage # Test coverage
# Database
deno task seed # Initialize seed data
# Code Quality
deno lint # Lint
deno fmt # Format
deno check **/*.ts # Type checkDeployment โ
Docker โ
bash
docker build -t halolight-deno .
docker run -p 8000:8000 halolight-denoDocker Compose โ
bash
docker-compose up -dyaml
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
environment:
- NODE_ENV=production
- JWT_SECRET=${JWT_SECRET}
- DENO_KV_PATH=/data/kv.db
volumes:
- deno_kv_data:/data
restart: unless-stopped
volumes:
deno_kv_data:Deno Deploy (Recommended) โ
bash
# Install deployctl
deno install -Arf jsr:@deno/deployctl
# Deploy to Deno Deploy
deployctl deploy --project=halolight-deno main.tsProduction Configuration โ
env
NODE_ENV=production
JWT_SECRET=your-production-secret-key-min-32-chars
DENO_KV_PATH=/data/kv.db
PORT=8000Testing โ
Run Tests โ
bash
deno test # Run all tests
deno test --coverage # Generate coverage report
deno test --watch # Watch modeTest Examples โ
typescript
// routes/api/auth/_test.ts
import { assertEquals } from "https://deno.land/std@0.208.0/assert/mod.ts";
Deno.test("POST /api/auth/login - success", async () => {
const response = await fetch("http://localhost:8000/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "admin@halolight.h7ml.cn",
password: "123456",
}),
});
assertEquals(response.status, 200);
const data = await response.json();
assertEquals(data.success, true);
assertEquals(typeof data.data.accessToken, "string");
});
Deno.test("POST /api/auth/login - invalid credentials", async () => {
const response = await fetch("http://localhost:8000/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "wrong@example.com",
password: "wrong",
}),
});
assertEquals(response.status, 401);
const data = await response.json();
assertEquals(data.success, false);
});Performance Metrics โ
Benchmarks โ
| Metric | Value | Notes |
|---|---|---|
| Request Throughput | ~45,000 req/s | Deno 2.0, single core, wrk test |
| Average Response Time | <5ms | Local Deno KV, no external deps |
| Memory Usage | ~30MB | Base memory after startup |
| CPU Usage | <10% | Idle state |
Observability โ
Logging System โ
typescript
// utils/logger.ts
import { Logger } from "https://deno.land/std@0.208.0/log/mod.ts";
const logger = new Logger("app");
export function logRequest(req: Request, res: Response, duration: number) {
logger.info(
`${req.method} ${new URL(req.url).pathname} ${res.status} ${duration}ms`,
);
}
export function logError(error: Error, context?: any) {
logger.error(`Error: ${error.message}`, { error, context });
}Health Check โ
typescript
// routes/api/health.ts
export const handler = async (req: Request): Promise<Response> => {
try {
// Check Deno KV connection
const kv = await Deno.openKv();
await kv.get(["health"]);
await kv.close();
return Response.json({
status: "healthy",
timestamp: new Date().toISOString(),
uptime: Deno.memoryUsage(),
});
} catch (error) {
return Response.json(
{ status: "unhealthy", error: error.message },
{ status: 503 },
);
}
};Monitoring Metrics โ
typescript
// utils/metrics.ts
const metrics = {
requests: 0,
errors: 0,
responseTime: [] as number[],
};
export function recordRequest(duration: number) {
metrics.requests++;
metrics.responseTime.push(duration);
}
export function recordError() {
metrics.errors++;
}
export function getMetrics() {
const avg = metrics.responseTime.reduce((a, b) => a + b, 0) /
metrics.responseTime.length;
return {
totalRequests: metrics.requests,
totalErrors: metrics.errors,
avgResponseTime: avg || 0,
};
}FAQ โ
Q: How to persist Deno KV data? โ
A: Configure the DENO_KV_PATH environment variable to specify the data file path.
bash
# .env
DENO_KV_PATH=./data/kv.dbtypescript
// Use custom path
const kv = await Deno.openKv(Deno.env.get("DENO_KV_PATH"));Q: How to enable remote Deno KV (Deno Deploy)? โ
A: When deploying on Deno Deploy, using Deno.openKv() automatically connects to the hosted distributed KV.
typescript
// Production environment automatically uses remote KV
const kv = await Deno.openKv();Q: How to handle file uploads? โ
A: Use Fresh's FormData API to handle file uploads.
typescript
// routes/api/files/upload.ts
export const handler = async (req: Request): Promise<Response> => {
const formData = await req.formData();
const file = formData.get("file") as File;
if (!file) {
return Response.json({ error: "No file uploaded" }, { status: 400 });
}
// Save file to Deno KV or cloud storage
const bytes = await file.arrayBuffer();
const kv = await Deno.openKv();
await kv.set(["files", crypto.randomUUID()], {
name: file.name,
type: file.type,
size: file.size,
data: new Uint8Array(bytes),
});
return Response.json({ success: true });
};Q: How does Islands architecture integrate with APIs? โ
A: Islands are client-side interactive components that call backend APIs via fetch.
typescript
// islands/UserList.tsx
import { useSignal } from "@preact/signals";
import { useEffect } from "preact/hooks";
export default function UserList() {
const users = useSignal([]);
useEffect(() => {
fetch("/api/users")
.then((res) => res.json())
.then((data) => users.value = data);
}, []);
return (
<div>
{users.value.map((user) => (
<div key={user.id}>{user.name}</div>
))}
</div>
);
}Development Tools โ
Recommended Tools/Plugins โ
- Deno VSCode Extension - Official VS Code plugin with IntelliSense and debugging
- deployctl - Deno Deploy command-line tool
- wrk / autocannon - HTTP stress testing tools
- Deno Lint - Built-in code linting tool
Comparison with Other Backends โ
| Feature | Deno Fresh | NestJS | FastAPI | Spring Boot |
|---|---|---|---|---|
| Language | TypeScript (Deno) | TypeScript | Python | Java |
| ORM | Deno KV | Prisma | SQLAlchemy | JPA |
| Performance | โญโญโญโญโญ | โญโญโญโญ | โญโญโญโญ | โญโญโญ |
| Learning Curve | โญโญโญโญ | โญโญโญ | โญโญโญโญ | โญโญ |
| Startup Time | <100ms | ~2s | ~1s | ~5s |
| Memory Usage | 30MB | 80MB | 50MB | 150MB |
| Deployment | Deno Deploy | Docker/Cloud | Docker/Cloud | Docker/Cloud |