ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Encore 元数据 API 完整指南:在 Go 应用中获取应用、环境与当前请求信息

Encore 元数据 API 完整指南:在 Go 应用中获取应用、环境与当前请求信息 Encore 元数据 API 完整指南在 Go 应用中获取应用、环境与当前请求信息【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encoreEncore 提供了内置的元数据 APIencore.dev包让运行中的 Go 应用可以随时查询我是谁、我跑在哪里、我为什么被调用这三类运行时信息。本指南基于 Encore 开源仓库中 docs/go/develop/metadata.md 与 runtimes/go/meta.go、runtimes/go/request.go 等源码实现完整讲解encore.Meta()与encore.CurrentRequest()的字段含义、底层原理与实战用例。读完后你将掌握如何区分云厂商与环境类型、如何在 raw endpoint 中拿到解析后的路径参数、如何在任意 goroutine 中追溯当前请求从而写出云无关、环境感知的健壮代码。为什么需要元数据 APIEncore 致力于提供云无关cloud-agnostic的开发体验同一个应用可以在本地、Encore Cloud、AWS、GCP、Azure 上以相同的方式运行。但有些场景下你确实需要知道自己运行在什么环境、由谁触发例如本地开发时跳过邮件验证、跳过外部依赖在 AWS 上把审计日志写入 Redshift在 GCP 上写入 BigQuery在 raw endpoint 中获取标准http.Request拿不到的路径参数。为此encore.dev包对外暴露了两组 APIApplication Metadata应用级元数据与Current Request当前请求元数据。Application Metadata应用与环境信息调用encore.Meta()会返回一个*encore.AppMetadata实例包含应用本身、运行环境、构建版本与部署信息。其入口定义在 runtimes/go/pkgfn.go底层实现在 runtimes/go/meta.go。import encore.dev meta : encore.Meta() // 永不返回 nilAppMetadata 字段详解AppMetadata结构体定义在 runtimes/go/meta.go共包含 5 个字段字段类型说明AppIDstring应用 ID。若应用未链接到 Encore 平台则为空字符串可在应用根目录执行encore app link完成链接APIBaseURLurl.URL应用 API 对外可公开访问的基础 URL。本地开发时为http://localhost:port通常是http://localhost:4000若环境配置了自定义域名custom domain此处会返回该域名但注意自定义域名可随时更新变更只在下次部署时生效EnvironmentEnvironmentMeta当前环境信息见下文BuildBuildMeta本次构建所基于的版本控制提交信息DeployDeployMeta部署 ID 与部署时间EnvironmentMeta环境名、类型与云厂商type EnvironmentMeta struct { Name string // 环境名本地开发时为 local Type EnvironmentType // 环境类型本地开发时为 EnvLocal Cloud CloudProvider // 云厂商本地开发时为 CloudLocal }EnvironmentMeta定义见 runtimes/go/meta.go。其中Type与Cloud是判断运行环境最常用的两个字段。环境类型EnvironmentType常量定义在 runtimes/go/meta.go常量值含义EnvProductionproduction生产环境EnvDevelopmentdevelopment长期存在的云端非生产环境如测试环境EnvEphemeralephemeral短期存在的云端非生产环境如随 PR 存活、PR 关闭即销毁的预览环境EnvLocallocal使用encore run/encore test运行的本地环境已废弃Encore 将不再返回该值本地运行可通过EnvDevelopment CloudLocal组合判断该常量将在未来版本移除EnvTesttest单元测试运行期间云厂商CloudProvider常量定义在 runtimes/go/meta.go其底层字符串值在 runtimes/go/appruntime/shared/cloud/clouds.go常量值含义CloudAWSawsAWSCloudGCPgcpGoogle CloudCloudAzureazureMicrosoft AzureEncoreCloudencoreEncore 自有云是新环境Environment的默认云厂商CloudLocallocal本地即通过 CLI 的encore run/encore test运行注意CloudProvider是开放集合——官方注释明确未来可能增加更多云厂商因此切换语句中保留default分支是良好的防御性写法。Build 与 Deploy构建与部署信息type BuildMeta struct { Revision string // 本次构建基于的 git 提交哈希 UncommittedChanges bool // 该提交之上是否存在未提交的改动 } type DeployMeta struct { ID string // Encore 平台生成的部署 ID Time time.Time // Encore 平台将本次构建部署到环境的时间 }定义见 runtimes/go/meta.go。这些信息直接来自运行时配置从 runtimes/go/appruntime/exported/config/config.go 可以看到Build.Revision来源于静态配置config.Static.AppCommitCommitInfo结构其中Uncommitted字段记录是否有未提交改动Deploy与Environment则来源于动态运行时配置config.RuntimeDeployID、DeployedAt、EnvName、EnvType、EnvCloud、AppSlug、APIBaseURL等字段见 config.go。Current Request当前请求信息encore.CurrentRequest()可以从应用的任意位置调用返回一个*encore.Request实例描述当前代码为什么正在运行。与Meta()一样入口定义在 runtimes/go/pkgfn.go实现见 runtimes/go/request.go。import encore.dev req : encore.CurrentRequest() // 永不返回 nil且每次调用返回新实例Request 核心字段Request结构体定义在 runtimes/go/request.go字段类型说明TypeRequestType触发本次代码运行的原因APICallAPI 调用、PubSubMessagePub/Sub 订阅消息、None无外部触发如包级init函数Startedtime.Time触发发生的时间Servicestring正在处理该请求的服务名Endpointstring被调用的 API 端点名Pathstring请求到达 API 服务器的路径PathParamsPathParams已解析的路径参数Methodstring使用的 HTTP 方法Headershttp.Header请求头当前在调用方与被调用方同进程的服务间调用中为空该行为未来可能改变Payloadany已解码的请求负载或 Pub/Sub 消息负载无请求负载或 raw endpoint 时为 nilAPI*APIDesc被调用 API 端点的元数据请求/响应类型、是否 raw、标签、是否公开、是否要求认证Trace*TraceData当前请求的追踪信息TraceID、SpanID、父 Trace/Span ID、外部关联 ID、是否被记录Message*MessageDataPub/Sub 消息特有信息仅当Type PubSubMessage时非空CronIdempotencyKeystring若请求由 Cron Job 触发则为该次执行的唯一 ID否则为空字符串可用于区分 Cron 触发与其他请求其中RequestType定义在 runtimes/go/request.go取值固定为none、api-call、pubsub-message三种。PathParamsraw endpoint 的路径参数利器PathParams是[]PathParam保留参数在 URL 中的顺序每个PathParam包含Name不含:或*前缀的参数名与Value解析后的值。它还提供了便捷方法Get(name string) string按名取值、不存在时返回空字符串实现在 runtimes/go/request.go。这对于 raw endpoints 尤其有价值raw endpoint 的http.Request对象无法直接访问解析后的路径参数而 rest API 中声明的路径参数如/user/:id会被 Encore 解析通过encore.CurrentRequest().PathParams()即可读取//encore:api raw methodGET path/user/:id func GetUser(w http.ResponseWriter, req *http.Request) { userID : encore.CurrentRequest().PathParams().Get(id) // ... }goroutine 追踪子 goroutine 中依然可用CurrentRequest()是 Encore 请求追踪机制request tracking自动工作的结果Encore 在 runtimes/go/appruntime/shared/reqtrack/reqtrack.go 中通过RequestTracker.Current()读取当前 goroutine关联的请求上下文。因此在请求处理期间派生的其他 goroutine 中调用仍会返回同一个请求信息即使请求 handler 已经返回从请求期间派生的 goroutine 中调用依然能报告原请求若调用方没有正在处理的请求例如在服务初始化阶段调用Type字段返回NoneStarted返回应用启动时间见 request.go。也正因为按 goroutine 追踪CurrentRequest()是并发安全的且每次调用返回全新实例可安全地由调用代码修改而不影响后续调用。实战用例基于环境切换实现用例一按云厂商切换服务实现云无关所有 Encore 支持的云 都包含大量 Encore 原生不支持的服务。利用 环境 信息可以为每个环境的云厂商定义不同的实现——例如审计日志写入GCP 用 BigQuery、AWS 用 Redshift、本地直接写文件package audit import ( encore.dev encore.dev/beta/auth ) func Audit(ctx context.Context, action message, user auth.UID) error { switch encore.Meta().Environment.Cloud { case encore.CloudAWS: return writeIntoRedshift(ctx, action, user) case encore.CloudGCP: return writeIntoBigQuery(ctx, action, user) case encore.CloudLocal: return writeIntoFile(ctx, action, user) default: return fmt.Errorf(unknown cloud: %s, encore.Meta().Environment.Cloud) } }仓库自带的示例测试 runtimes/go/example_test.go 展示了同样的按云切换模式印证了这是一种官方认可的标准用法。用例二按环境类型跳过邮件验证实现注册系统时你可能希望在开发阶段跳过邮件验证、直接标记用户已验证生产环境才真正发送验证邮件。利用encore.Meta()检查环境类型即可package user import encore.dev //encore:api public func Signup(ctx context.Context, params *SignupParams) (*SignupResponse, error) { // ... // 如果是测试环境跳过发送验证邮件 switch encore.Meta().Environment.Type { case encore.EnvTest, encore.EnvDevelopment: if err : MarkEmailVerified(ctx, userID); err ! nil { return nil, err } default: if err : SendVerificationEmail(ctx, userID); err ! nil { return nil, err } } // ... }同样地runtimes/go/example_test.go 给出了用encore.Meta().Environment.Type ! encore.EnvProduction判断非生产环境的最简写法。用例三记录请求耗时与调用来源CurrentRequest()还能配合req.Started计算请求已运行时长并获取服务与端点名用于日志func ExampleCurrentRequest() { req : encore.CurrentRequest() elapsed : time.Since(req.Started) if req.Type encore.APICall { fmt.Printf(%s.%s has been running for %.3f seconds, req.Service, req.Endpoint, elapsed.Seconds()) } }该示例同样来自 runtimes/go/example_test.go是官方文档中的规范用法。源码级原理元数据从哪来从实现角度总结元数据 API 的数据链路encore.Meta()Manager.Meta()从运行时配置config.Runtime读取AppSlug、APIBaseURL、EnvName、EnvType、EnvCloud、DeployID、DeployedAt从静态配置config.Static读取构建提交信息AppCommit组装成AppMetadata返回见 runtimes/go/meta.go。APIBaseURL在NewManager中即被解析为url.URL非法 URL 会直接 panic见 meta.go。encore.CurrentRequest()通过单例Manager由 pkgfn.go 中的Singleton NewManager(...)创建持有的RequestTracker按 goroutine 关联读取当前请求若当前请求是 RPC 调用RPCCall/AuthHandler填充APICall相关的服务、端点、路径、路径参数、方法、请求头、负载与APIDesc若是PubSubMessage则填充消息主题、订阅、ID、投递时间与重试次数等MessageData字段见 runtimes/go/request.go。其中 Cron 触发的请求通过请求头X-Encore-Cron-Execution识别并填入CronIdempotencyKey。追踪基础RequestTracker在请求开始BeginRequest时还会把父请求的用户 ID、认证数据、TraceID、关联 ID 等信息复制到子请求保证服务间调用链上元数据连续见 runtimes/go/appruntime/shared/reqtrack/reqtrack.go。最佳实践与注意事项Meta()与CurrentRequest()永不返回 nil可以放心直接解引用但字段在特定场景下为空如未链接平台的AppID、非 API 调用时的API/Endpoint、非 Cron 触发的CronIdempotencyKey使用前应判断。EnvLocal已废弃判断本地开发请用Environment.Type encore.EnvDevelopment Environment.Cloud encore.CloudLocal避免依赖即将移除的常量。CloudProvider是开放集合switch 时务必带default分支兼容未来新增的云厂商。raw endpoint 取路径参数不要试图手工解析req.URL.Path直接用encore.CurrentRequest().PathParams().Get(id)Encore 已按 rest API 声明完成解析。不要在Meta()结果上做持久化假设环境、部署信息每次调用实时组装与当前运行时配置一致适合在启动时缓存一次供全局使用。至此你已经掌握了 Encore 元数据 API 的全部核心能力既能通过encore.Meta()感知应用、环境、构建与部署的全局信息也能通过encore.CurrentRequest()在任意 goroutine 中追溯请求来源与路径参数足以支撑环境感知、云无关的 Go 服务实现。【免费下载链接】encoreThe infrastructure platform for the intelligence era项目地址: https://gitcode.com/GitHub_Trending/encor/encore创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表