Files
v-hono/README.MD
T
2025-07-07 11:27:17 +08:00

6.3 KiB
Raw Blame History

V-Hono

一个用 V 语言编写的轻量级 Web 框架,灵感来自 Hono.js。

特性

  • 🚀 高性能路由系统(混合路由算法)
  • 🎯 类似 Hono.js 的 Context API
  • 🔧 洋葱模型中间件支持
  • 📦 内置 LRU 缓存系统
  • 🛠️ 支持动态路由参数(:param)
  • ⚡ 支持通配符路由(* 和 **)
  • 🔄 支持所有 HTTP 方法(GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS)
  • 🏗️ 构造函数风格的 API 设计

安装

# 克隆仓库
git clone https://github.com/your-username/v-hono.git
cd v-hono

# 运行示例
v run example.v

快速开始

module main

import hono
import net.http

fn main() {
    mut app := hono.new_hono()
    
    // 基本路由
    app.get('/', fn (mut c hono.Context) http.Response {
        return c.html('<h1>Hello V-Hono!</h1>')
    })
    
    app.get('/api/users/:id', fn (mut c hono.Context) http.Response {
        user_id := c.params['id']
        return c.json('{"id": "${user_id}", "name": "John Doe"}')
    })
    
    app.post('/api/users', fn (mut c hono.Context) http.Response {
        c.status(201)
        return c.json('{"message": "User created", "data": "${c.body}"}')
    })
    
    // 中间件
    app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
        println('[LOG] ${c.url}')
        return next(mut c)
    })
    
    app.listen(':3000')
}

API 参考

Context

Context 是请求的核心对象,包含所有请求和响应信息:

pub struct Context {
pub:
    req    http.Request      // 原始 HTTP 请求
    params map[string]string // 路径参数
    query  map[string]string // 查询参数
    url    string           // 请求 URL
pub mut:
    status_code int = 200   // 响应状态码
    headers     map[string]string // 响应头
    body        string      // 响应体
}

构造函数

所有对象都使用构造函数风格创建:

// 创建 Context
ctx := hono.Context.new(req, params, query, body)

// 创建路由器
router := hono.ContextHybridRouter.new()
trie_router := hono.ContextTrieRouter.new()

// 创建缓存
cache := hono.ContextLRUCache.new(1000)

路由方法

支持所有 HTTP 方法:

// GET 请求
app.get('/path', fn (mut c hono.Context) http.Response {
    return c.json('{"message": "GET response"}')
})

// POST 请求
app.post('/path', fn (mut c hono.Context) http.Response {
    return c.json('{"message": "POST response"}')
})

// PUT 请求
app.put('/path', fn (mut c hono.Context) http.Response {
    return c.json('{"message": "PUT response"}')
})

// DELETE 请求
app.delete('/path', fn (mut c hono.Context) http.Response {
    c.status(204)
    return c.text('')
})

// PATCH 请求
app.patch('/path', fn (mut c hono.Context) http.Response {
    return c.json('{"message": "PATCH response"}')
})

// HEAD 请求
app.head('/path', fn (mut c hono.Context) http.Response {
    return c.text('')
})

// OPTIONS 请求
app.options('/path', fn (mut c hono.Context) http.Response {
    return c.text('')
})

动态路由

支持路径参数和通配符:

// 单参数
app.get('/users/:id', fn (mut c hono.Context) http.Response {
    user_id := c.params['id']
    return c.json('{"id": "${user_id}"}')
})

// 多参数
app.get('/posts/:id/comments/:comment_id', fn (mut c hono.Context) http.Response {
    post_id := c.params['id']
    comment_id := c.params['comment_id']
    return c.json('{"post_id": "${post_id}", "comment_id": "${comment_id}"}')
})

// 嵌套参数
app.get('/api/users/:user_id/posts/:post_id', fn (mut c hono.Context) http.Response {
    user_id := c.params['user_id']
    post_id := c.params['post_id']
    return c.json('{"user_id": "${user_id}", "post_id": "${post_id}"}')
})

// 通配符
app.get('/files/*', fn (mut c hono.Context) http.Response {
    file_path := c.params['*']
    return c.text('File: ${file_path}')
})

// 多级通配符
app.get('/api/**/search', fn (mut c hono.Context) http.Response {
    return c.json('{"search": "wildcard"}')
})

响应方法

所有响应方法直接返回 http.Response:

// JSON 响应
return c.json('{"message": "Hello"}')

// 文本响应
return c.text('Hello World')

// HTML 响应
return c.html('<h1>Hello</h1>')

// 设置状态码
c.status(404)
return c.json('{"error": "Not Found"}')

中间件

支持洋葱模型中间件:

// 日志中间件
app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
    println('[${time.now()}] ${c.req.method} ${c.url}')
    return next(mut c)
})

// 认证中间件
app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
    token := c.query['token']
    if token == '' {
        c.status(401)
        return c.json('{"error": "Unauthorized"}')
    }
    return next(mut c)
})

// 性能监控中间件
app.use(fn (mut c hono.Context, next fn (mut hono.Context) http.Response) http.Response {
    start := time.now()
    response := next(mut c)
    duration := time.now() - start
    println('请求处理时间: ${duration.milliseconds()}ms')
    return response
})

查询参数和请求体

// 获取查询参数
app.get('/search', fn (mut c hono.Context) http.Response {
    query := c.query['q']
    page := c.query['page']
    return c.json('{"query": "${query}", "page": "${page}"}')
})

// 获取请求体
app.post('/api/data', fn (mut c hono.Context) http.Response {
    println('请求体: ${c.body}')
    return c.json('{"received": "${c.body}"}')
})

路由统计和缓存

// 获取路由统计信息
static_count, dynamic_count, cache_size, cache_capacity := app.get_router_stats()
println('静态路由: ${static_count}, 动态路由: ${dynamic_count}')
println('缓存: ${cache_size}/${cache_capacity}')

// 清理缓存
app.clear_cache()

示例

运行完整示例:

v run example.v

示例包含:

  • 静态路由
  • 动态路由(单参数、多参数、嵌套参数)
  • 所有 HTTP 方法
  • 中间件功能
  • 参数提取和查询参数处理

性能特性

  • 混合路由算法:静态路由 O(1) 查找,动态路由正则匹配
  • LRU 缓存:自动缓存路由匹配结果
  • Trie 路由树:支持复杂路径匹配
  • 内存优化:使用指针和堆分配优化性能

贡献

欢迎提交 Issue 和 Pull Request!

许可证

MIT License