Dagger ServiceEndpointOpts 完全指南:掌握 TypeScript 服务端点的 port 与 scheme 配置
Dagger ServiceEndpointOpts 完全指南掌握 TypeScript 服务端点的 port 与 scheme 配置【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger导读ServiceEndpointOpts是 Dagger TypeScript SDKdagger.io/dagger中用于配置服务端点Service Endpoint查询参数的类型别名。在 Dagger 中Container可以被转换为可提供 TCP 连接的Service而Service.endpoint()方法则负责返回客户端可用于访问该服务的地址。ServiceEndpointOpts正是该方法的核心入参通过port指定目标端口通过scheme决定返回 URL 还是host:port地址对。读完本文你将掌握该类型的所有字段语义、默认行为、底层实现原理并能在 Go / TypeScript 模块中写出可运行的端点消费代码。ServiceEndpointOpts 是什么在 docs/versioned_docs/version-0.19/reference/typescript/api/client.gen/type-aliases/ServiceEndpointOpts.md 中ServiceEndpointOpts被定义为ServiceEndpointOptsobject它是一个对象类型用于描述调用Service.endpoint()时可选的配置项。该类型由 Dagger 的代码生成器从 GraphQL API 的serviceEndpointArgs参数自动生成其真实定义可以在 sdk/typescript/src/api/client.gen.ts#L2824-L2834 中查看export type ServiceEndpointOpts { /** * The exposed port number for the endpoint */ port?: number /** * Return a URL with the given scheme, eg. http for http:// */ scheme?: string }其中两个字段均为可选optional。这正是 Dagger 声明式引擎设计理念的体现所有输入都有合理的默认行为调用方只需在需要精确控制时显式传入参数。字段详解port?: number —— 端点暴露的端口号属性说明字段名port类型number是否必填否可选语义端点对应的暴露端口号port用于指定要返回的服务端口。如果不传该字段Dagger 会回退到第一个暴露的端口the first exposed port即服务上通过withExposedPort()设置端口列表中的第一个端口如果服务没有暴露任何端口则会返回错误no ports exposed。这一行为在 core/service.go#L390-L396 的引擎端实现中有直接体现if port 0 { if len(svc.Container.Self().Ports) 0 { return , fmt.Errorf(no ports exposed) } port svc.Container.Self().Ports[0].Port }从源码结构看当port为 0即未指定时引擎会优先读取容器自身已暴露的端口列表取第一个端口作为默认值。因此在使用endpoint()之前务必先通过Container.withExposedPort()声明端口否则会得到错误。port参数在 GraphQL 层的定义位于 core/schema/service.go#L118-L121属于endpoint节点的serviceEndpointArgstype serviceEndpointArgs struct { Port dagql.Optional[dagql.Int] Scheme string default: }注意Scheme有默认值空字符串而Port是可选的Optional。scheme?: string —— 端点 URL 的协议前缀属性说明字段名scheme类型string是否必填否可选语义返回带指定协议的 URL例如http对应http://scheme用于控制返回值的格式传入 scheme如http、https、tcp等endpoint()返回一个完整 URL格式为scheme://host:port不传 schemeendpoint()返回一个host:port地址对如127.0.0.1:8080。这一格式化的实现位于 core/service.go#L433-L438endpoint : fmt.Sprintf(%s:%d, host, port) if scheme ! { endpoint scheme :// endpoint } return endpoint, nil也就是说scheme本质上是在host:port前面拼接scheme://前缀。文档中的示例注释 eg. http for http:// 精确描述了这一行为。Service.endpoint()ServiceEndpointOpts 的消费方ServiceEndpointOpts唯一的直接消费场景就是 Service 类 的endpoint()方法。其 TypeScript 签名如下endpoint(opts?: ServiceEndpointOpts): Promisestring官方文档对该方法的语义描述为Retrieves an endpoint that clients can use to reach this container. If no port is specified, the first exposed port is used. If none exist an error is returned. If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned.翻译过来即获取一个客户端可用于访问该容器的端点未指定端口时使用第一个暴露的端口若无暴露端口则报错指定 scheme 时返回 URL否则返回host:port地址对。在 sdk/typescript/src/api/client.gen.ts#L14168-L14178 中可以看到其实现方法会将整个opts对象透传给 GraphQL 查询的endpoint字段由引擎计算后返回字符串endpoint async (opts?: ServiceEndpointOpts): Promisestring { if (this._endpoint) { return this._endpoint } const ctx this._ctx.select(endpoint, { ...opts }) const response: Awaitedstring await ctx.execute() return response }Service 类中的相关方法为了更好理解endpoint()在服务生命周期中的位置可以参考 Service 类文档 中与之配套的常用方法hostname()获取客户端可用于访问该容器的主机名Promisestringports()获取服务提供的端口列表PromisePort[]start()启动服务并等待健康检查通过PromiseServicestop(opts?)停止服务PromiseServiceup(opts?)创建隧道将调用方网络流量转发到该服务PromisevoidwithHostname(hostname)为当前会话内的客户端配置访问该容器的主机名。其中hostname()与endpoint()的关系最为密切endpoint()返回的地址中的host部分正是通过服务的主机名解析得到的。在引擎端 core/service.go#L384-L388当服务基于容器时会先调用svc.Hostname(ctx, dig)取得主机名case svc.Container.Self() ! nil: host, err svc.Hostname(ctx, dig)实战如何正确使用 ServiceEndpointOpts下面给出官方文档配套的完整可运行示例。该示例位于 docs/versioned_docs/version-0.19/extending/modules/snippets/services/use-endpoint/typescript/index.ts演示了启动 NGINX 服务 → 获取端点 → 发起 HTTP 请求的完整链路import { dag, object, func } from dagger.io/dagger object() export class MyModule { func() async get(): Promisestring { // start NGINX service let service dag.container().from(nginx).withExposedPort(80).asService() service await service.start() // wait for service to be ready const endpoint await service.endpoint({ port: 80, scheme: http }) // send HTTP request to service endpoint return await dag.http(endpoint).contents() } }步骤拆解构建服务dag.container().from(nginx).withExposedPort(80).asService()拉取nginx镜像、暴露 80 端口并将其转换为Service。注意withExposedPort(80)是必需的它决定了后续endpoint()能查到哪些端口启动服务await service.start()显式启动服务并等待健康检查通过。文档特别指出绑定到Container上的服务无需手动启动而这里因为是独立服务所以需要显式调用获取端点await service.endpoint({ port: 80, scheme: http })—— 这里显式传入了ServiceEndpointOpts的两个字段port: 80指定端口scheme: http要求返回http://开头的 URL。最终结果形如http://hostname:80消费端点dag.http(endpoint).contents()使用返回的 URL 发起 HTTP 请求并读取响应内容。对比不传 opts 的默认行为如果调用service.endpoint()不传任何选项则端口回退为第一个暴露端口即上面例子中的 80返回host:80这样的地址对而不是 URL。此时若直接丢给dag.http()使用会因为缺少协议前缀而失败。这正是scheme字段存在的意义在需要 URL 型地址如 HTTP 客户端时显式指定scheme让返回值可直接使用。其它语言的等价用法ServiceEndpointOpts不仅在 TypeScript SDK 中存在同名结构也被 Dagger 的代码生成器输出到各个 SDK 中例如sdk/go/dagger.gen.goGo SDKsdk/python/runtime/internal/dagger/dagger.gen.goPython SDKsdk/java/runtime/internal/dagger/dagger.gen.goJava SDKsdk/rust/crates/dagger-sdk/src/gen.rsRust SDKsdk/elixir/runtime/internal/dagger/dagger.gen.goElixir SDKsdk/php/runtime/internal/dagger/dagger.gen.goPHP SDK。以官方 Go 版示例 docs/versioned_docs/version-0.19/extending/modules/snippets/services/use-endpoint/go/main.go 为例用法完全对应package main import ( context dagger/my-module/internal/dagger ) type MyModule struct{} func (m *MyModule) Get(ctx context.Context) (string, error) { // Start NGINX service service : dag.Container().From(nginx).WithExposedPort(80).AsService() service, err : service.Start(ctx) if err ! nil { return , err } // Wait for service endpoint endpoint, err : service.Endpoint(ctx, dagger.ServiceEndpointOpts{Scheme: http, Port: 80}) if err ! nil { return , err } // Send HTTP request to service endpoint return dag.HTTP(endpoint).Contents(ctx) }可以看到Go 中通过结构体字面量dagger.ServiceEndpointOpts{Scheme: http, Port: 80}传参字段语义与 TypeScript 完全一致。底层原理端口回退与 scheme 拼接从引擎实现core/service.go#L375-L439看endpoint()的完整逻辑可归纳为以下流程确定 host根据服务类型分支处理——容器型服务通过svc.Hostname(ctx, dig)取得主机名隧道型服务TunnelUpstream从已启动的隧道实例中取得tunnel.Host主机 socket 型服务HostSockets同样使用主机名并从第一个 socket 的端口转发中推导端口其它类型返回 unknown service type 错误。确定 port若传入port 0则直接使用否则取服务端口列表中的第一个端口列表为空则报错。拼装结果先组成host:port若scheme非空则在前面拼接scheme://。值得注意的实现细节是endpoint节点在 GraphQL 层被标记为DoNotCache见 core/schema/service.go#L113-L117原因正如注释所说——A tunnel services endpoint can change if tunnel service is restarted隧道服务重启后端点可能变化因此该查询不会被缓存每次调用都会重新计算。常见问题与注意事项未暴露端口就调用 endpoint()会得到no ports exposed错误。务必先用withExposedPort()声明端口或将port参数显式传入。不传 scheme 时返回的是地址对而非 URL若下游消费方如dag.http()、fetch()需要完整 URL必须显式传scheme。端口必须是已暴露的端口即使显式传入了port若该端口并未通过withExposedPort()暴露不同服务类型下的行为可能不同最稳妥的做法是保证port与withExposedPort声明一致。endpoint()不会被缓存由于隧道类服务重启后端点可能变化每次调用都会实时计算这保证了获取到的地址始终是最新的运行状态。总结ServiceEndpointOpts是 Dagger 服务网络能力中一个轻量但关键的配置类型port?: number控制端点端口缺省时回退到第一个暴露端口scheme?: string控制返回格式缺省返回host:port传入后返回scheme://host:port它与Container.withExposedPort()、Service.start()、Service.hostname()等 API 紧密配合是启动服务 → 获取可访问地址 → 消费服务这一经典链路中不可或缺的一环。无论是编写 Dagger 模块TypeScript / Go / Python / Java / Rust / Elixir / PHP SDK 通用还是在集成测试中动态获取被测服务地址理解ServiceEndpointOpts的字段语义与默认行为都能帮助你写出更健壮、可预期的服务消费代码。【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

UFO² 集成 Anthropic Claude:从 API 配置到源码级调用链实战指南

UFO² 集成 Anthropic Claude:从 API 配置到源码级调用链实战指南

UFO 集成 Anthropic Claude:从 API 配置到源码级调用链实战指南 【免费下载链接】UFO UFO: Weaving the Digital Agent Galaxy 项目地址: https://gitcode.com/GitHub_Trending/uf/UFO UFO(UFO 系列开源项目)的智能体框架支持将 Anthr…

2026/10/25 21:37:20 阅读更多 →
OpenMetadata Drive 服务元数据采集管道配置指南:过滤器模式、实体开关与删除标记详解

OpenMetadata Drive 服务元数据采集管道配置指南:过滤器模式、实体开关与删除标记详解

OpenMetadata Drive 服务元数据采集管道配置指南:过滤器模式、实体开关与删除标记详解 【免费下载链接】OpenMetadata The Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for…

2026/10/24 9:37:01 阅读更多 →
v.douyin.com短链生成全攻略:从手动复制到程序化批量实操

v.douyin.com短链生成全攻略:从手动复制到程序化批量实操

大家应该都见过这种文本:一串类似7.12 复制打开抖音,看看【某某的作品】... https://v.douyin.com/vtezwc4lj6k/ :9pm 02/15 ba.nq kcu:/的消息,里面藏着一条以v.douyin.com开头的短链接。做抖音运营、搞投放监测、写数据采集脚本的朋友&…

2026/10/25 16:48:34 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/30 0:01:36 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/30 9:20:34 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/30 10:19:21 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/30 0:01:37 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/30 10:19:39 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/30 9:21:37 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/29 17:01:10 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 10:28:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 0:01:33 阅读更多 →