flatend Context完全指南:Handler、Headers与Body的实战用法
【免费下载链接】flatendQuickly build microservices using p2p networking in NodeJS/Go.项目地址: https://gitcode.com/gh_mirrors/fl/flatend
flatend 是一款基于 p2p 网络快速构建微服务的开源框架,同时支持 Go 与 NodeJS。本文将以flatend Context为核心,带你彻底搞懂三个最关键的概念:Handler(服务处理函数)、Headers(请求/响应头)与Body(请求体)。无论你是刚开始接触 p2p 微服务的新手,还是想快速上手的普通用户,读完这篇实战指南,你就能独立写出第一个 flatend 服务。
flatend 是什么:用 p2p 思想做微服务 🚀
传统微服务需要注册中心、网关、负载均衡等一堆基础设施,而 flatend 的思路完全不同:节点之间直接通过 p2p 网络互连,服务按名字暴露,其他节点按名字调用,不需要中心服务器。
- ✅ 同时支持Go和NodeJS,两边可以互调服务
- ✅ 服务注册、发现、路由全部自动完成
- ✅ 基于流式传输,天然适合大文件、长连接场景
在 flatend 中,一个服务的核心就是一个Handler,它接收一个Context对象,Context 里带着本次调用的全部信息:Headers(头部)、Body(请求体),以及向调用方写回数据的能力。
Handler:如何注册一个 flatend 服务处理函数
Go 版本:一分钟注册服务
在 Go 中,Handler 是一个函数类型func(ctx *Context),定义在 net.go。把处理函数塞进Node.Services字典即可:
node := &flatend.Node{ Services: map[string]flatend.Handler{ "hello_world": func(ctx *flatend.Context) { ctx.Write([]byte("Hello world!")) }, }, } node.Start("127.0.0.1:9000")完整示例可参考 examples/go/hello_world/main.go。
NodeJS 版本:写法更简洁
在 NodeJS 中,Context 是一个继承自流(Duplex)的对象,使用ctx.send()一行返回数据:
const node = await Node.start({ addrs: [`127.0.0.1:9000`], services: { hello_world: (ctx) => ctx.send("Hello world!"), }, });完整示例见 examples/nodejs/hello_world/index.js。
💡要点:服务名就是"微服务地址"。Go 节点注册的
hello_world,NodeJS 节点可以直接调用,反之亦然,这就是 flatend 跨语言互通的魅力。
Headers:flatend 中请求头如何传递
Context 的Headers字段(Go 中为map[string]string)保存着调用方传来的头部信息。理解它的最佳方式是看HTTP 网关层是怎么做的——flathttp/service.go 会把 HTTP 请求自动转成 flatend 调用:
| 来源 | 转换规则 | 示例 |
|---|---|---|
| HTTP 请求头 | 转为小写 key | Authorization→authorization |
| URL 查询参数 | 加query.前缀 | ?id=5→query.id |
| 路由参数 | 加params.前缀 | /user/:id→params.id |
也就是说,你可以在业务代码里这样读取:
func handler(ctx *flatend.Context) { token := ctx.Headers["authorization"] userId := ctx.Headers["params.id"] }这个设计非常实用:HTTP 网关只负责协议转换,业务服务完全不用感知 HTTP,天然实现协议解耦。路由配置本身也很直观,见 flathttp/config.go:
[[http.routes]] path = "GET /api/user/:id" service = "user_service"如何设置响应头
- Go:在写入数据前调用
ctx.WriteHeader(key, val),例如ctx.WriteHeader("content-type", "application/json") - NodeJS:调用
ctx.header(key, val),返回的依然是 Context,支持链式调用:
services: { api: (ctx) => ctx.header("content-type", "application/json").json({ ok: true }), },NodeJS 里还内置了ctx.json()方法,自动帮你设置content-type并序列化,特别适合写 API(见 context.ts)。
Body:读取与发送请求体
读取请求体:Go 用流,NodeJS 用 body()
Go 的 Context 中,Body是一个io.ReadCloser,可以像普通文件一样流式读取:
func uploadHandler(ctx *flatend.Context) { data, _ := io.ReadAll(ctx.Body) // 一次性读完 defer ctx.Body.Close() }NodeJS 更省心,直接await ctx.body()就能拿到完整内容,还支持大小限制:
services: { echo: async (ctx) => { const data = await ctx.body({ limit: 1024 * 1024 }); // 最大 1MB ctx.send(data); }, },默认限制是 65536 字节(64KB),超限会抛出异常,防止恶意请求撑爆内存。源码见 context.ts。
流式写入:边读边发
flatend 的 Context 本身就是流,你可以边接收边转发,非常适合做**管道(pipe)**服务:
func pipeHandler(ctx *flatend.Context) { _, _ = io.Copy(ctx, ctx.Body) // 请求体直接透传为响应 }项目自带的 pipe 示例 就是靠这一行实现的流式管道,NodeJS 对应版本在 examples/nodejs/pipe/index.js,两者可以互相连通,值得亲自跑一遍。
实战:一个完整的 flatend 计数器服务
把上面三个概念串起来,写一个"调用一次加一"的计数器服务(参考 examples/go/counter/main.go):
counter := uint64(0) node := &flatend.Node{ Services: map[string]flatend.Handler{ "count": func(ctx *flatend.Context) { current := atomic.AddUint64(&counter, 1) - 1 ctx.WriteHeader("x-count", strconv.FormatUint(current, 10)) // 响应头 ctx.Write(strconv.AppendUint(nil, current, 10)) // 响应体 }, }, } node.Start("127.0.0.1:9000")调用方(另一个节点)通过Push发起请求:
stream, err := node.Push([]string{"count"}, headers, body)- 第一个参数:目标服务名列表
- 第二个参数:Headers 字典
- 第三个参数:请求体
返回的stream.Reader就是响应体,stream.Header.Headers则是响应头,Push的定义可查看 provider.go。
小结:三件事记住就入门了
| 概念 | Go | NodeJS | 一句话总结 |
|---|---|---|---|
| Handler | func(ctx *flatend.Context) | (ctx) => ... | 注册到node.Services里的服务函数 |
| Headers | ctx.Headers[...]/ctx.WriteHeader(k,v) | ctx.headers/ctx.header(k,v) | 传递元数据,HTTP 网关会自动转换 |
| Body | io.ReadAll(ctx.Body) | await ctx.body({limit}) | 读取请求体,也可ctx.Write/send回写 |
flatend 的 Context 设计兼顾了 Go 的严谨与 NodeJS 的简洁:Handler 决定"干什么",Headers 传递"上下文",Body 承载"数据"。理解了这三者的协作方式,再去看 flathttp 网关层、nodejs/src/ 的源码实现,你会发现整个 p2p 微服务架构瞬间变得清晰起来。
下一步,不妨打开 examples/go/hello_world/main.go 或 examples/nodejs/hello_world/index.js,跑通第一个 flatend 服务,再试着把 HTTP 网关接进来,感受一下 p2p 微服务的开发效率。
【免费下载链接】flatendQuickly build microservices using p2p networking in NodeJS/Go.项目地址: https://gitcode.com/gh_mirrors/fl/flatend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考