当然可以。让我们深入探讨更复杂的场景,并进一步细化上述内容。

  1. 高级类型定义

首先,让我们定义更复杂的类型结构:

enum UserRole {
  Admin = 'admin',
  User = 'user',
  Guest = 'guest'
}
 
interface Address {
  street: string;
  city: string;
  country: string;
  postalCode: string;
}
 
interface UserDetails {
  age: number;
  email: string;
  phone?: string;
  address: Address;
}
 
interface ComplexParam {
  id: number;
  name: string;
  role: UserRole;
  details: UserDetails;
  tags: string[];
  preferences: Record<string, boolean>;
  lastLogin: Date;
}
  1. 高级后端路由处理

使用 Elysia 的高级特性来处理这个复杂结构:

import { Elysia, t } from 'elysia'
 
const addressSchema = t.Object({
  street: t.String(),
  city: t.String(),
  country: t.String(),
  postalCode: t.String()
})
 
const userDetailsSchema = t.Object({
  age: t.Number(),
  email: t.String(),
  phone: t.Optional(t.String()),
  address: addressSchema
})
 
const app = new Elysia()
  .post('/process-complex', ({ body }) => {
    const data = body as ComplexParam;
    // 复杂处理逻辑
    return `Processed: ${data.name}, role ${data.role}`;
  }, {
    body: t.Object({
      id: t.Number(),
      name: t.String(),
      role: t.Enum(UserRole),
      details: userDetailsSchema,
      tags: t.Array(t.String()),
      preferences: t.Record(t.String(), t.Boolean()),
      lastLogin: t.String() // 将作为字符串接收,然后转换为Date
    })
  })
  1. 高级前端 HTMX 实现

创建一个更复杂的表单,包含嵌套对象和数组:

<form hx-post="/process-complex" hx-trigger="submit" hx-target="#result">
  <input type="hidden" name="id" value="1">
  <input type="text" name="name" value="John Doe">
  <select name="role">
    <option value="admin">Admin</option>
    <option value="user">User</option>
    <option value="guest">Guest</option>
  </select>
  <fieldset>
    <legend>Details</legend>
    <input type="number" name="details.age" value="30">
    <input type="email" name="details.email" value="john@example.com">
    <input type="tel" name="details.phone" value="+1234567890">
    <fieldset>
      <legend>Address</legend>
      <input type="text" name="details.address.street" value="123 Main St">
      <input type="text" name="details.address.city" value="Anytown">
      <input type="text" name="details.address.country" value="USA">
      <input type="text" name="details.address.postalCode" value="12345">
    </fieldset>
  </fieldset>
  <div id="tags-container">
    <input type="text" name="tags[]" value="tag1">
    <input type="text" name="tags[]" value="tag2">
  </div>
  <button type="button" onclick="addTag()">Add Tag</button>
  <fieldset>
    <legend>Preferences</legend>
    <label><input type="checkbox" name="preferences.newsletter" value="true"> Newsletter</label>
    <label><input type="checkbox" name="preferences.notifications" value="true"> Notifications</label>
  </fieldset>
  <input type="datetime-local" name="lastLogin">
  <button type="submit">Submit</button>
</form>
<div id="result"></div>
 
<script>
function addTag() {
  const container = document.getElementById('tags-container');
  const input = document.createElement('input');
  input.type = 'text';
  input.name = 'tags[]';
  container.appendChild(input);
}
</script>
  1. 处理复杂数据转换

在后端,我们需要处理一些数据转换:

app.post('/process-complex', ({ body }) => {
  const complexParam: ComplexParam = {
    id: body.id,
    name: body.name,
    role: body.role as UserRole,
    details: {
      age: body.details.age,
      email: body.details.email,
      phone: body.details.phone,
      address: body.details.address
    },
    tags: Array.isArray(body.tags) ? body.tags : [body.tags].filter(Boolean),
    preferences: Object.entries(body.preferences || {}).reduce((acc, [key, value]) => {
      acc[key] = value === 'true';
      return acc;
    }, {} as Record<string, boolean>),
    lastLogin: new Date(body.lastLogin)
  };
 
  // 进一步处理逻辑
  return JSON.stringify(complexParam);
})
  1. 实现部分更新 (PATCH)

添加一个 PATCH 端点来处理部分更新:

App.Patch ('/update-complex/: id', ({ params, body }) => {
  const id = parseInt(params.id);
  // 假设我们有一个获取现有数据的函数
  const existingData = getExistingData(id);
  
  const updatedData: Partial<ComplexParam> = {
    ...existingData,
    ...body,
    details: body.details ? { ...existingData.details, ...body.details } : existingData.details,
    preferences: body.preferences ? { ...existingData.preferences, ...body.preferences } : existingData.preferences
  };
 
  // 更新逻辑
  return `Updated: ${updatedData.name}`;
})
  1. 实现文件上传

添加文件上传功能:

import { Elysia, t } from 'elysia'
import { multipart } from '@elysiajs/multipart'
 
app.use(multipart())
 
app.post('/upload', async ({ body }) => {
  const file = body.file as File;
  // 处理文件上传
  await Bun.write(`uploads/${file.name}`, file);
  return `File ${file.name} uploaded successfully`;
}, {
  body: t.Object({
    file: t.File()
  })
})

前端 HTMX 文件上传:

<form hx-post="/upload" hx-encoding="multipart/form-data" hx-target="#upload-result">
  <input type="file" name="file">
  <button type="submit">Upload</button>
</form>
<div id="upload-result"></div>
  1. 实现分页和过滤

添加一个支持分页和过滤的 GET 端点:

app.get('/list-complex', ({ query }) => {
  const page = parseInt(query.page as string) || 1;
  const limit = parseInt(query.limit as string) || 10;
  const filter = query.filter as string;
 
  // 假设有一个获取数据的函数
  const data = getComplexData(page, limit, filter);
 
  return JSON.stringify(data);
})

前端 HTMX 实现:

<div hx-get="/list-complex?page=1&limit=10" hx-trigger="load">
  <!-- 数据将被加载到这里 -->
</div>
<input type="text" name="filter" hx-get="/list-complex" hx-trigger="keyup changed delay:500ms" hx-target="#data-container">
<div id="data-container"></div>
  1. 使用 WebSocket 进行实时更新

使用 Elysia 的 WebSocket 支持实现实时更新:

import { Elysia, t } from 'elysia'
import { websocket } from '@elysiajs/websocket'
 
app.use(websocket())
 
app.ws('/realtime', {
  message(ws, message) {
    // 处理接收到的消息
    console.log(message);
    // 广播消息给所有连接的客户端
    ws.send(`Received: ${message}`);
  }
})

前端 HTMX WebSocket 实现:

<div hx-ws="connect:/realtime">
  <div id="messages"></div>
  <form hx-ws="send:submit">
    <input type="text" name="message">
    <button type="submit">Send</button>
  </form>
</div>
  1. 错误处理和日志记录

实现全局错误处理和日志记录:

import { Elysia } from 'elysia'
import { logger } from '@elysiajs/logger'
 
const app = new Elysia()
  .use(logger())
  .onError(({ code, error, set }) => {
    console.error(`Error ${code}: ${error.message}`);
    set.status = code === 'NOT_FOUND' ? 404 : 500;
    return { error: error.message };
  })
  1. 使用中间件进行认证

实现一个简单的 JWT 认证中间件:

import { Elysia } from 'elysia'
import { jwt } from '@elysiajs/jwt'
 
const app = new Elysia()
  .use(jwt({
    name: 'jwt',
    secret: 'your-secret-key'
  }))
  .derive(({ jwt }) => ({
    signToken: (payload: any) => jwt.sign(payload),
    verifyToken: (token: string) => jwt.verify(token)
  }))
  .derive(({ request, verifyToken }) => ({
    auth: async () => {
      const token = request.headers.get('Authorization')?.split(' ')[1];
      if (!token) throw new Error('No token provided');
      const payload = await verifyToken(token);
      if (!payload) throw new Error('Invalid token');
      return payload;
    }
  }))
 
app.get('/protected', async ({ auth }) => {
  const user = await auth();
  return `Welcome, ${user.name}!`;
})

这个扩展版本涵盖了更多高级主题,包括复杂的数据结构、文件上传、分页、实时通信、错误处理、认证等。它展示了如何在 Elysia 和 HTMX 的架构中处理各种复杂场景,同时保持代码的类型安全和可维护性。这种方法允许你构建功能丰富、响应迅速的全栈应用,充分利用 Bun 运行时的性能优势。