Initial commit: Bun web server with middleware, routing, and comprehensive documentation

This commit is contained in:
2025-12-11 23:56:40 +09:00
commit faea4e4d1f
25 changed files with 3404 additions and 0 deletions

510
README.md Normal file
View File

@ -0,0 +1,510 @@
# 🚀 Bun Web Server
Современный, быстрый и масштабируемый веб-сервер на основе **Bun** с поддержкой middleware, маршрутизации и SSR.
## 📋 Оглавление
- [Быстрый старт](#быстрый-старт)
- [Структура проекта](#структура-проекта)
- [API Endpoints](#api-endpoints)
- [Middleware](#middleware)
- [Как расширять](#как-расширять)
- [Примеры](#примеры)
## 🚀 Быстрый старт
### Установка зависимостей
```bash
bun install
```
### Разработка (с hot reload)
```bash
bun run dev
```
Сервер запустится на `http://localhost:3000`
### Запуск в продакшене
```bash
bun run start
```
### Сборка для продакшена
```bash
bun run build
```
## 📁 Структура проекта
```
src/
├── index.ts # Точка входа приложения
├── server.ts # Класс Server (основной сервер)
├── router.ts # Класс Router (маршрутизация)
├── middleware.ts # Система middleware
├── render.ts # SSR рендеринг для React компонентов
├── utils.ts # Вспомогательные функции
├── types.ts # TypeScript типы и интерфейсы
├── handlers/
│ ├── homeHandler.ts # Обработчик главной страницы
│ └── apiHandler.ts # Обработчики API endpoints
├── middleware/
│ ├── builtIn.ts # Встроенные middleware (logging, CORS, etc)
│ └── advanced.ts # Продвинутые middleware (caching, validation)
└── components/
├── Layout.tsx # React компонент Layout
├── UI.tsx # UI компоненты (Button, Endpoint)
└── pages/
└── HomePage.tsx # React компонент главной страницы
```
### Описание ключевых файлов
| Файл | Описание |
|------|---------|
| `server.ts` | Основной класс сервера. Управляет портом, маршрутами и middleware |
| `router.ts` | Маршрутизатор. Регистрирует и сопоставляет HTTP методы с обработчиками |
| `middleware.ts` | Система цепочки middleware для обработки запросов |
| `handlers/` | Обработчики запросов для каждого маршрута |
| `middleware/builtIn.ts` | Готовые middleware: логирование, CORS, обработка ошибок, rate limiting |
| `middleware/advanced.ts` | Продвинутые middleware: кеширование, валидация, сжатие |
| `utils.ts` | Вспомогательные функции для формирования ответов |
## 🌐 API Endpoints
### Главная страница
```
GET /
```
Возвращает HTML страницу с интерактивным интерфейсом для тестирования endpoints.
**Ответ:** HTML (200)
---
### Приветствие
```
GET /api/hello
```
Простой JSON endpoint с приветствием.
**Ответ:**
```json
{
"success": true,
"data": {
"message": "Hello from Bun API! 👋",
"timestamp": "2025-12-11T14:35:00.000Z"
}
}
```
---
### Статус сервера
```
GET /api/status
```
Возвращает информацию о состоянии сервера.
**Ответ:**
```json
{
"success": true,
"data": {
"status": "online",
"uptime": 1234.56,
"timestamp": "2025-12-11T14:35:00.000Z",
"memory": {
"rss": 52428800,
"heapTotal": 16777216,
"heapUsed": 8388608
}
}
}
```
---
### Эхо данных
```
POST /api/echo
```
Возвращает отправленные данные обратно.
**Body:**
```json
{
"message": "Hello from Bun!",
"timestamp": "2025-12-11T14:35:00.000Z"
}
```
**Ответ:**
```json
{
"success": true,
"data": {
"echo": {
"message": "Hello from Bun!",
"timestamp": "2025-12-11T14:35:00.000Z"
},
"receivedAt": "2025-12-11T14:35:00.000Z"
}
}
```
---
## 🔗 Middleware
Middleware выполняются по цепочке и могут модифицировать запрос и ответ.
### Встроенные Middleware
| Middleware | Описание |
|-----------|---------|
| `errorHandlingMiddleware` | Глобальная обработка ошибок |
| `loggingMiddleware` | Логирование всех запросов с временем выполнения |
| `rateLimitMiddleware` | Ограничение количества запросов (100 в минуту) |
| `corsMiddleware` | Добавление CORS заголовков |
| `authMiddleware` | Проверка авторизации (Bearer token) |
### Продвинутые Middleware
| Middleware | Описание |
|-----------|---------|
| `cachingMiddleware` | Кеширование GET запросов с настраиваемым TTL |
| `compressionMiddleware` | Поддержка сжатия ответов |
| `validationMiddleware` | Валидация входных данных |
### Пример использования middleware:
```typescript
const middlewareChain = server.getMiddleware();
middlewareChain.use(errorHandlingMiddleware);
middlewareChain.use(loggingMiddleware);
middlewareChain.use(rateLimitMiddleware);
middlewareChain.use(corsMiddleware);
```
## 📚 Как расширять
### 1. Добавить новый API endpoint
Создайте файл обработчика в `src/handlers/`:
**src/handlers/userHandler.ts**
```typescript
import { jsonResponse, errorResponse } from "../utils";
export async function getUserHandler(_req: Request, url: URL): Promise<Response> {
const userId = url.searchParams.get("id");
if (!userId) {
return errorResponse("Missing user ID", 400);
}
return jsonResponse({
id: userId,
name: "John Doe",
email: "john@example.com"
});
}
export async function createUserHandler(req: Request, _url: URL): Promise<Response> {
try {
const body = await req.text();
const data = body ? JSON.parse(body) : {};
if (!data.name || !data.email) {
return errorResponse("Name and email are required", 400);
}
return jsonResponse({
id: Math.random().toString(36).substr(2, 9),
...data
}, 201);
} catch (error) {
return errorResponse("Invalid JSON", 400);
}
}
```
Затем добавьте маршруты в `src/index.ts`:
```typescript
import { getUserHandler, createUserHandler } from "./handlers/userHandler";
// ...
const router = server.getRouter();
// Добавляем новые маршруты
router.get("/api/users", getUserHandler);
router.post("/api/users", createUserHandler);
```
### 2. Создать новый Middleware
Создайте файл в `src/middleware/`:
**src/middleware/custom.ts**
```typescript
import type { MiddlewareHandler } from "../middleware";
export const customHeaderMiddleware: MiddlewareHandler = async (req, url, next) => {
// Логика перед запросом
console.log(`Custom middleware: ${req.method} ${url.pathname}`);
const response = await next();
// Логика после запроса
const headers = new Headers(response.headers);
headers.set("X-Custom-Header", "My Value");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers,
});
};
```
Добавьте в `src/index.ts`:
```typescript
import { customHeaderMiddleware } from "./middleware/custom";
const middlewareChain = server.getMiddleware();
middlewareChain.use(customHeaderMiddleware);
```
### 3. Добавить React компонент страницы
Создайте компонент в `src/components/pages/`:
**src/components/pages/AboutPage.tsx**
```typescript
import React from "react";
import { Layout } from "../Layout";
export function AboutPage() {
return (
<Layout title="About - Bun Server">
<div style={{ padding: "40px", background: "white", borderRadius: "12px" }}>
<h1>About Page</h1>
<p>Это страница About, созданная с помощью React компонентов!</p>
</div>
</Layout>
);
}
```
Добавьте обработчик в `src/handlers/`:
**src/handlers/pageHandler.ts**
```typescript
export async function aboutHandler(_req: Request, _url: URL): Promise<Response> {
const html = `<!DOCTYPE html>
<html>
<head>
<title>About</title>
</head>
<body>
<h1>About Page</h1>
<p>Добро пожаловать на страницу About!</p>
</body>
</html>`;
return new Response(html, {
headers: { "Content-Type": "text/html; charset=utf-8" },
});
}
```
И зарегистрируйте маршрут в `src/index.ts`:
```typescript
router.get("/about", aboutHandler);
```
### 4. Добавить базу данных
Пример с простой in-memory базой:
**src/db.ts**
```typescript
interface User {
id: string;
name: string;
email: string;
}
class Database {
private users: Map<string, User> = new Map();
createUser(name: string, email: string): User {
const id = Math.random().toString(36).substr(2, 9);
const user = { id, name, email };
this.users.set(id, user);
return user;
}
getUser(id: string): User | undefined {
return this.users.get(id);
}
getAllUsers(): User[] {
return Array.from(this.users.values());
}
}
export const db = new Database();
```
Используйте в handlers:
```typescript
import { db } from "../db";
export async function createUserHandler(req: Request): Promise<Response> {
const body = await req.text();
const { name, email } = body ? JSON.parse(body) : {};
const user = db.createUser(name, email);
return jsonResponse(user, 201);
}
```
## 💡 Примеры
### Пример 1: Добавить простой JSON endpoint
```typescript
// src/handlers/dataHandler.ts
export async function getDataHandler(_req: Request, _url: URL): Promise<Response> {
return jsonResponse({
items: [
{ id: 1, name: "Item 1" },
{ id: 2, name: "Item 2" },
]
});
}
// src/index.ts
router.get("/api/data", getDataHandler);
```
### Пример 2: Добавить параметры в URL
```typescript
export async function getUserByIdHandler(_req: Request, url: URL): Promise<Response> {
const id = url.searchParams.get("id");
if (!id) {
return errorResponse("ID is required", 400);
}
return jsonResponse({ id, name: `User ${id}` });
}
// Использование: GET /api/users?id=123
```
### Пример 3: POST с валидацией
```typescript
export async function createItemHandler(req: Request, _url: URL): Promise<Response> {
try {
const body = await req.text();
const data = body ? JSON.parse(body) : {};
if (!data.name || data.name.trim() === "") {
return errorResponse("Name is required", 400);
}
return jsonResponse({
id: Math.random().toString(36).substr(2, 9),
name: data.name,
createdAt: new Date().toISOString()
}, 201);
} catch (error) {
return errorResponse("Invalid JSON", 400);
}
}
```
## 🔧 Конфигурация
### Изменить порт сервера
В `src/index.ts`:
```typescript
const server = new Server({ port: 8080 }); // Вместо 3001
```
### Добавить новые HTTP методы
В `src/router.ts` уже реализованы методы:
- `get(path, handler)`
- `post(path, handler)`
- `put(path, handler)`
- `delete(path, handler)`
- `patch(path, handler)`
Если нужен дополнительный метод:
```typescript
export class Router {
// ... существующий код ...
public options(path: string, handler: RouteHandler): void {
this.routes.push({ method: "OPTIONS", path, handler });
}
}
```
## 📊 Логирование
По умолчанию включено логирование через `loggingMiddleware`:
```
📨 [2025-12-11T14:35:00.000Z] GET /api/hello
✅ GET /api/hello - 200 (1.09ms)
```
Для добавления кастомного логирования:
```typescript
export const customLoggingMiddleware: MiddlewareHandler = async (req, url, next) => {
console.log(`[${new Date().toISOString()}] Custom log for ${url.pathname}`);
return next();
};
```
## 🚀 Развертывание
### На Heroku
```bash
git push heroku main
```
### На VPS
```bash
bun run build
bun run start
```
## 📝 Лучшие практики
1. **Структура папок**: Держите обработчики и middleware в отдельных папках
2. **Типизация**: Используйте TypeScript для всех критических частей
3. **Ошибки**: Используйте `errorResponse()` для консистентных ошибок
4. **Middleware**: Добавляйте middleware в правильном порядке (ошибки → логирование → другие)
5. **Validation**: Всегда валидируйте входные данные
6. **Comments**: Добавляйте комментарии к сложным логикам
## 📄 Лицензия
MIT