
RPC框架后端微服务【免费下载链接】twirpA simple RPC framework with protobuf service definitions项目地址https://gitcode.com/gh_mirrors/tw/twirp点击查看免费下载Twirp 是一个强调简洁与极简的服务间通信框架它从 Protobuf API 定义文件自动生成路由与序列化代码让开发者专注业务逻辑而无需操心 HTTP 方法与路径细节。本文以官方示例文档docs/example.md为主体完整演示如何用 5 个步骤从零构建一个经典的Haberdasher制帽匠服务编写.proto定义、用protoc生成代码、实现服务端接口、挂载 HTTP 服务、调用自动生成的强类型客户端。读完本文你将掌握 Twirp 服务的完整开发闭环并能对照仓库内可运行的 example 实例加深理解。快速总览5 步构建一个 Twirp 服务Haberdasher服务只提供一个 RPC 方法MakeHat给定帽子尺寸英寸返回一顶随机颜色的新帽子。整个流程分 5 步编写 Protobuf 服务定义.proto文件用protoc生成 Go 代码.pb.go与.twirp.go实现服务端接口业务逻辑挂载并运行 HTTP 服务使用自动生成的客户端调用最终效果跑起一个带强类型客户端的 Haberdasher 服务。仓库 example 目录下已有一个完整可运行的对应实现cmd/server与cmd/client两个可执行程序可以边读边对照。动手前请先确认环境就绪参照 docs/install.md 安装protoc、protoc-gen-go与protoc-gen-twirp。第 1 步编写 Protobuf 服务定义在rpc/haberdasher/service.proto中编写 proto3 定义syntax proto3; package twirp.example.haberdasher; option go_package github.com/example/rpc/haberdasher; // Haberdasher service makes hats for clients. service Haberdasher { // MakeHat produces a hat of mysterious, randomly-selected color! rpc MakeHat(Size) returns (Hat); } // Size of a Hat, in inches. message Size { int32 inches 1; // must be 0 } // A Hat is a piece of headwear made by a Haberdasher. message Hat { int32 inches 1; string color 2; // anything but invisible string name 3; // i.e. bowler }几点建议与说明文件即文档为.proto文件补充注释非常值得这些文件可以作为 API 的首要文档。注释还会原样出现在生成的 Go 类型上——打开 example/service.twirp.go 可以看到// A Haberdasher makes hats for clients.与// MakeHat produces a hat of mysterious, randomly-selected color!都直接透传到了生成的Haberdasher接口上。option go_package指定生成的 Go 代码所属的包导入路径是生成器解析跨文件 import 的关键依据详见 docs/command_line.md。字段约束约定inches必须大于 0、颜色不能是 invisible这些约束在 proto 中只是注释约定真正强制执行要靠服务端业务代码见第 3 步的参数校验。仓库 example/service.proto 中的定义与文档略有差异消息字段名为size而非inches、包名为twitch.twirp.example但结构完全一致可互为参考。第 2 步生成代码使用protoc编译器同时指定--go_out生成 Protobuf 消息代码与--twirp_out生成 Twirp 路由与客户端代码$ protoc --go_out. --twirp_out. \ --go_optpathssource_relative \ --twirp_optpathssource_relative \ rpc/haberdasher/service.proto生成的文件会落在.proto文件同目录下/rpc /haberdasher service.proto service.pb.go # generated by protoc-gen-go service.twirp.go # generated by protoc-gen-twirp关于生成参数的补充说明pathssource_relative让生成文件与.proto源文件保持相对路径关系仓库 example/gen.go 中的go:generate指令正是这样写的protoc --go_outpathssource_relative:. --twirp_outpathssource_relative:. service.proto。--twirp_out与--go_out支持相同的参数体系包括import_prefix导入前缀和M导入映射用于多 proto 文件跨包 import 时的路径替换详细说明见 docs/command_line.md。打开生成的.twirp.go文件会看到类似这样的 Go 接口// A Haberdasher makes hats for clients. type Haberdasher interface { // MakeHat produces a hat of mysterious, randomly-selected color! MakeHat(context.Context, *Size) (*Hat, error) }此外生成文件还包含实例化客户端与服务端的代码。从 example/service.twirp.go 的源码可以看到生成物的完整结构客户端实现haberdasherProtobufClient与haberdasherJSONClient两个结构体分别通过doProtobufRequest/doJSONRequest发起请求服务端处理器haberdasherServer结构体实现了ServeHTTP负责请求解析、路由匹配与方法分发example/service.twirp.go版本断言文件开头有const _ twirp.TwirpPackageMinVersion_8_1_0用于校验生成的代码与运行时库版本兼容详见 docs/version_matrix.md。第 3 步实现服务端现在编写满足Haberdasher接口的业务代码也就是处理请求的“后端逻辑”。实现可以放在internal/haberdasherserver/server.gopackage haberdasherserver import ( context math/rand github.com/twitchtv/twirp pb github.com/example/rpc/haberdasher ) // Server implements the Haberdasher service type Server struct {} func (s *Server) MakeHat(ctx context.Context, size *pb.Size) (hat *pb.Hat, err error) { if size.Inches 0 { return nil, twirp.InvalidArgumentError(inches, I cant make a hat that small!) } return pb.Hat{ Inches: size.Inches, Color: []string{white, black, brown, red, blue}[rand.Intn(5)], Name: []string{bowler, baseball cap, top hat, derby}[rand.Intn(4)], }, nil }这里的实现要点接口实现即业务层Twirp 的哲学是服务端只需实现生成接口序列化、路由、错误包装全部由生成的处理器代劳。仓库 example/cmd/server/main.go 中的randomHaberdasher是同一模式的真实实现。参数校验与错误返回当Inches 0时返回twirp.InvalidArgumentError(inches, I cant make a hat that small!)。查看 errors.go 的源码可知该构造函数会创建InvalidArgument类型的错误并把参数名写入错误元数据metaargument方便客户端定位是哪个参数校验失败。随机选择rand.Intn从预置的颜色/款式列表中随机挑选正好呼应 proto 注释里“神秘随机颜色”的设定。第 4 步挂载并运行服务要基于 HTTP 提供 Haberdasher 服务使用生成的New{{Service}}Server构造函数。对 Haberdasher 而言其签名是func NewHaberdasherServer(svc Haberdasher, opts ...interface{}) TwirpServer这个构造函数把你的接口实现包装成一个TwirpServer——它本质是一个带额外能力的http.Handler。因此可以像挂载任何 HTTP handler 一样把它挂到标准库服务器上。在cmd/server/main.go中package main import ( net/http github.com/example/internal/haberdasherserver github.com/example/rpc/haberdasher ) func main() { server : haberdasherserver.Server{} // implements Haberdasher interface twirpHandler : haberdasher.NewHaberdasherServer(server) http.ListenAndServe(:8080, twirpHandler) }运行go run ./cmd/server/main.go服务即监听在localhost:8080。底层机制与扩展点从 example/service.twirp.go 的源码可以确认选项机制NewHaberdasherServer接受twirp.ServerOption修饰器如twirp.WithServerHooks(hooks)并通过ReadOpt读取jsonSkipDefaults、jsonCamelCase、pathPrefix等选项其中pathPrefix默认值为/twirp。路由格式为[prefix]/package.Service/Method例如POST /twirp/twitch.twirp.example.Haberdasher/MakeHat参考 example/service.twirp.go 中导出的HaberdasherPathPrefix常量更多路由细节见 docs/routing.md。只用 POSTServeHTTP会拒绝非 POST 请求并返回badRouteErrorexample/service.twirp.go这是 Twirp 路由协议的一部分见 docs/mux.md。可组合的中间件生态TwirpServer仍是普通http.Handler可与其他中间件链式组合也可通过 ServerHooks如 example/cmd/server/main.go 里接入的statsd.NewStatsdServerHooks观测指标——运行仓库示例服务时控制台会打印类似incr twirp.MakeHat.requests、time twirp.MakeHat.response的统计日志见 example/cmd/server/README.md。第 5 步使用客户端客户端存根是自动生成的。每个服务有 2 个客户端构造函数New{{Service}}ProtobufClient使用 Protobuf 编码请求。New{{Service}}JSONClient使用 JSON 编码请求。推荐使用ProtobufClientProtobuf 与 JSON 的取舍对比见 docs/protobuf_and_json.md。其他语言也可通过各自语言的protoc插件生成客户端例如--twirp_ruby_outTwirp 社区提供了 Ruby、Python、Rust、TypeScript 等多语言实现。要在另一个 Go 项目中调用Haberdasher服务导入自动生成的客户端即可。例如在cmd/client/main.go中package main import ( context net/http os fmt github.com/example/rpc/haberdasher ) func main() { client : haberdasher.NewHaberdasherProtobufClient(http://localhost:8080, http.Client{}) hat, err : client.MakeHat(context.Background(), haberdasher.Size{Inches: 12}) if err ! nil { fmt.Printf(oh no: %v, err) os.Exit(1) } fmt.Printf(I have a nice new hat: %v, hat) }在另一个终端保持服务运行然后执行go run ./cmd/client/main.go就能拿到一顶新帽子。客户端内部的实现细节可以从生成的源码中进一步印证URL 拼接客户端构造时按baseURL[prefix]/package.Service/Method拼接每个方法的 URLexample/service.twirp.go默认前缀同样是/twirp并可通过ClientOption调整pathPrefix、literalURLs等选项。上下文标注每个 RPC 调用都会通过ctxsetters.WithPackageName/WithServiceName/WithMethodName把服务与方法信息注入contextexample/service.twirp.go供拦截器与 hooks 使用见 ctxsetters/ctxsetters.go。拦截器支持客户端支持twirp.ChainInterceptors链式拦截器在每次调用前后插入横切逻辑example/service.twirp.go。错误处理非 2xx 响应会被转换为twirp.Error返回仓库 example/cmd/client/main.go 演示了利用twerr.Meta(retryable)判断错误是否可重试、从而自动重试的用法。小结与延伸阅读至此你已经走完了 Twirp 的完整开发闭环写 proto → 生成代码 → 实现接口 → 挂载 HTTP → 调用客户端。核心体验是路由、序列化、错误协议等“样板胶水”全部由代码生成器产出你只需要专注MakeHat这样的业务方法本身。如果希望进一步深入仓库中的相关文档与源码值得继续探索生成器的全部命令行参数与导入映射docs/command_line.mdTwirp 错误模型与各类错误构造函数如InvalidArgumentError、InternalErrorWithdocs/errors.md 与 errors.go拦截器与 hooks 机制docs/hooks.md、interceptors.go运行库与服务端选项ServerOption、ClientOptionserver_options.go、client_options.go完整可运行的参考实现example/service.proto、example/cmd/server/main.go、example/cmd/client/main.go赞分享RPC框架后端微服务【免费下载链接】twirpA simple RPC framework with protobuf service definitions项目地址https://gitcode.com/gh_mirrors/tw/twirp点击查看免费下载相关推荐Twirp项目实战构建Haberdasher微服务教程Twirp项目实战构建Haberdasher微服务教程 前言 在微服务架构中RPC远程过程调用框架扮演着重要角色。Twirp是一个轻量级的RPC框架由RPC框架后端微服务CyberStrikeAI 自定义 SQL 注入测试技能实战指南CyberStrikeAI 自定义 SQL 注入测试技能实战指南 CyberStrikeAI 是一套 AI 原生的安全运营平台意图进、受控执行出。这篇文章带网络安全渗透测试人工智能大模型AI AgentRAG后端前端MCP 服务漏洞扫描Dapr Proto 契约与代码生成实战指南从 Protobuf 定义到 gRPC 客户端Dapr Proto 契约与代码生成实战指南从 Protobuf 定义到 gRPC 客户端 本文聚焦 Dapr 核心仓库GitHub_Trending/da后端微服务云原生消息队列AI Agent上一篇Firecrawl MCP Server终极网页抓取工具完整指南下一篇终极指南如何用深度学习模型从文本中精准检测个性特征 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考