flatend Context完全指南:Handler、Headers与Body的实战用法
2026/8/18 14:46:57 网站建设 项目流程

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 网络互连,服务按名字暴露,其他节点按名字调用,不需要中心服务器。

  • ✅ 同时支持GoNodeJS,两边可以互调服务
  • ✅ 服务注册、发现、路由全部自动完成
  • ✅ 基于流式传输,天然适合大文件、长连接场景

在 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 请求头转为小写 keyAuthorizationauthorization
URL 查询参数query.前缀?id=5query.id
路由参数params.前缀/user/:idparams.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。


小结:三件事记住就入门了

概念GoNodeJS一句话总结
Handlerfunc(ctx *flatend.Context)(ctx) => ...注册到node.Services里的服务函数
Headersctx.Headers[...]/ctx.WriteHeader(k,v)ctx.headers/ctx.header(k,v)传递元数据,HTTP 网关会自动转换
Bodyio.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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询