ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Encore 中如何接收常规 HTTP 请求:Raw Endpoints 完整实战指南

Encore 中如何接收常规 HTTP 请求:Raw Endpoints 完整实战指南 Encore 中如何接收常规 HTTP 请求Raw Endpoints 完整实战指南【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore本指南以 Encore 开源仓库中的 http-requests.md 为核心骨架讲解如何在 Go 后端服务中定义raw endpoints原始端点直接以标准 Go HTTP handler 的形式接收来自外部系统的 Webhook、WebSocket 流量等常规 HTTP 请求并读取路径参数。读完本文你将掌握 raw endpoint 的注解写法、签名约束、路径参数读取方式及其底层解析与运行时实现原理能够直接落地到自己的 Encore 应用中。为什么需要 Raw EndpointsEncore 声明式 API//encore:api定义的 endpoint会在运行时自动完成请求反序列化、响应序列化、schema 校验等工作适合对 API schema 有完全掌控力的场景。但有些场景需要更底层的控制权典型如接收第三方服务的 Webhook 回调Webhook 的请求体、签名头、重试语义往往由外部系统决定无法套用 Encore 的 schema 约束使用 WebSocket 与客户端双向流式传输数据需要直接操作连接升级和帧读写透传 / 代理场景需要原样拿到原始请求头、原始 body甚至自己决定返回的 HTTP 状态码与响应内容。在这些情况下Encore 允许你定义raw endpoint——它工作在更低一层的抽象上直接暴露底层net/http请求与响应对象。用官方文档的原话说For these use cases Encore lets you define raw endpoints. Raw endpoints operate at a lower abstraction level, giving you access to the underlying HTTP request.文档原文见 http-requests.md。定义 Raw Endpoint定义 raw endpoint 只需修改//encore:api注解并改变函数签名。在:method、:id等路径之外raw endpoint 的函数签名是标准的 Go HTTP handlerpackage service import net/http // Webhook receives incoming webhooks from Some Service That Sends Webhooks. //encore:api public raw methodPOST path/webhook func Webhook(w http.ResponseWriter, req *http.Request) { // ... operate on the raw HTTP request ... }这里有两个关键点注解中的raw选项告诉 Encore 这是一个原始端点不进行 schema 解析与响应编码函数签名必须是func(http.ResponseWriter, *http.Request)这正是 Go 标准库net/http.Handler的签名形式。如果你是一名有经验的 Go 开发者这本质上就是一个普通的 Go HTTP handler文档原文If youre an experienced Go developer, this is just a regular Go HTTP handler。注解选项解析从 Encore 解析器的实现v2/parser/apis/api/api.go可以看到//encore:api注解支持以下选项与字段类别取值说明访问选项public/private/auth端点访问级别默认private端点选项raw声明为原始端点端点选项sensitive标记请求/响应数据为敏感信息字段path/xxx路由路径支持:param、*wildcard、!fallback通配段字段methodPOSTHTTP 方法可多值如methodGET,POST必须全大写签名校验规则解析器对 raw endpoint 的校验非常严格initRawRPCapi.go#L249-L270参数必须恰好两个http.ResponseWriter与*http.Request不允许有任何返回值第一个参数必须是net/http.ResponseWriter第二个参数必须是*http.Request。一旦违反会得到明确的编译期错误。对应的错误信息定义在 v2/parser/apis/api/errors.go例如Raw APIs must have a two parameters of type http.ResponseWriter and *http.Request, got %d parameters.Raw APIs must not return any results, got %d results.Raw APIs must have a first parameter of type http.ResponseWriter.校验测试用例见 v2/parser/apis/api/api_test.go其中用//encore:api public raw path/raw搭配func Raw(w http.ResponseWriter, req *http.Request) {}验证了该模式。注意raw endpoint不能声明为private。解析器会直接报错Private APIs cannot be declared as raw endpoints.见 errors.go#L42-L45因为私有 API 需要依赖类型化的调用协议与原始端点的设计冲突。HTTP 方法默认值如果注解中省略了method字段raw endpoint 默认接受所有 HTTP 方法源码中默认值为*见 api.go#L144-L158。而普通非 raw端点在没有请求体时默认接受GET与POST有请求体时默认仅POST。因此在定义 Webhook 时建议总是显式写明methodPOST避免意外暴露。读取路径参数很多 Webhook 会在 URL 路径中携带业务信息如用户 ID、订单号、回调资源 ID需要取出用于校验或后续处理。做法分两步在path中定义路径参数以:开头命名在函数内通过encore.CurrentRequest()获取当前请求上下文用PathParams.Get(name)读取。示例来自 http-requests.mdpackage service import ( net/http encore.dev ) //encore:api public raw methodPOST path/webhook/:id func Webhook(w http.ResponseWriter, req *http.Request) { id : encore.CurrentRequest().PathParams.Get(id) // ... Do something with id }CurrentRequest 的底层实现encore.CurrentRequest()返回一个*Request结构体其中包含丰富的请求元数据。其定义与实现位于 runtimes/go/request.goType请求触发类型api-call/pubsub-message/noneService/Endpoint处理该请求的服务名与端点名Path请求的原始路径PathParams解析后的路径参数Method请求使用的 HTTP 方法Headers请求头http.HeaderTrace包含 TraceID、SpanID 等分布式追踪信息。PathParams的类型是[]PathParam每个PathParam由Name与Value两个字段构成。Get(name)方法按名称线性查找并返回对应值若参数不存在则返回空字符串request.go#L137-L147。参数顺序会保持与 URL 中出现的顺序一致。CurrentRequest()的实现从当前协程的运行时上下文中读取请求数据request.go#L149-L217若当前没有活动请求则返回一个Type: None的空请求对象若是 API 调用则填充上述字段并将端点描述信息如Raw、Tags、Exposed、AuthRequired放入API字段。路径参数的进阶语法除了:name形式的命名参数Encore 的路由还支持通配段。路径解析逻辑集中在 v2/internals/resourcepaths/paths.go其段类型包括语法类型语义:name命名参数匹配单个路径段*nameWildcard匹配零个或多个路径段且必须是路径的最后一段!nameFallback匹配零个或多个路径段作为兜底路由同样必须是最后一段例如path/webhook/:id只匹配/webhook/123这一层而path/files/*path可以匹配/files/a/b/c.txt这类多级路径。路径参数的类型也有约束解析器在 validatePathParamapi.go#L272-L298 中校验参数类型必须是string、bool、各类整型int/int8/int16/int32/int64及uint系列或encore.dev/types/uuid.UUID。特别地通配段wildcard/fallback必须是字符串类型错误信息为Wildcard parameter %q must be a string.。对于 raw endpoint路径参数不会自动绑定到函数参数上——因为在func(w http.ResponseWriter, req *http.Request)签名中没有位置放它们统一通过encore.CurrentRequest().PathParams获取。Raw Endpoint 的运行时执行流程在运行时层面raw endpoint 与普通端点在处理链路上有明显差异。相关实现位于 runtimes/go/appruntime/apisdk/api/handler.go端点描述结构Desc中同时持有RawHandler func(http.ResponseWriter, *http.Request)与类型化的AppHandler二者互斥handler.go#L81-L96请求到达后若是 raw endpoint 则调用invokeHandlerRaw直接以http.HandlerFunc(d.RawHandler)的形式执行你的处理函数handler.go#L434-L447普通端点则走invokeHandlerNonRaw经历请求反序列化与响应编码流程。两条路径互不兼容——源码中两处panic明确区分invokeHandlerNonRaw called on Raw endpoint与invokeHandlerRaw called on non-Raw endpoint。从调用链看raw endpoint 仍然会经过 Encore 的中间件链路invokeHandlerRaw接收middleware.Request参数这一点与普通端点一致。请求与响应捕获raw endpoint 虽然让你直接操作原始请求与响应但 Encore 仍会为可观测性捕获请求/响应内容handler.go#L136-L137 与 handler.go#L312-L322请求侧使用rawRequestBodyCapturer包装*http.Request响应侧使用rawResponseCapturer包装http.ResponseWriter记录响应头与响应体。这些捕获的数据最终进入追踪tracing系统因此即使你手写w.Write(...)、手动设置状态码Dev Dashboard 中依然能看到该请求的入参、出参与响应状态——这正是 raw endpoint 在完全掌控 HTTP与保留 Encore 可观测性之间的平衡点handler.go#L945-L967。一个值得注意的限制Raw endpoint不能在 Encore 应用内部被调用。解析器会拒绝在服务代码中直接调用 raw endpoint对应错误为Raw APIs cannot be called from within an Encore application.errors.go#L133-L136。这是合理的raw endpoint 返回裸 HTTP 响应而非结构化数据无法被类型化的服务间调用协议表达。因此它只能作为对外暴露的入口使用。实战建议明确只做入口不做出口把 raw endpoint 当作应用的最外层适配器收到请求后解析所需字段路径参数、请求头、body尽快转成内部结构化数据交给普通逻辑处理保持服务内部仍是类型安全的。显式指定 methodWebhook 场景务必写methodPOST若端点逻辑与具体方法无关再考虑省略以接受所有方法。不要忘记自己写响应raw endpoint 没有 Encore 替你序列化响应必须手动调用w.WriteHeader(...)与w.Write(...)否则客户端会收到空响应。善用encore.CurrentRequest()除了路径参数它还能拿到Trace与Headers可用于 Webhook 签名校验如校验请求头中的签名或透传追踪 ID。WebSocket 场景在 raw handler 中拿到*http.Request与http.ResponseWriter后即可配合github.com/gorilla/websocket或标准库完成连接升级与双向消息流。延伸阅读原始端点的完整规范文档raw-endpoints.md普通 API 端点与 schema 定义defining-apis.md中间件如何作用于端点含 raw endpointmiddleware.md端点的运行时元数据encore.CurrentRequest的更多字段metadata.md解析器实现v2/parser/apis/api/api.go、v2/parser/apis/api/errors.go路径路由解析实现v2/internals/resourcepaths/paths.go运行时实现runtimes/go/request.go、runtimes/go/appruntime/apisdk/api/handler.go【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表