资讯动态

Activepieces Piece 开发实战:HTTP 客户端与 Common Patterns 完整指南

发布时间:2026/9/12 15:09:15 来源:尧图企业网站定制
Activepieces Piece 开发实战HTTP 客户端与 Common Patterns 完整指南【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces本文基于 Activepieces 开源仓库的 Piece Builder 技能文档 整理系统讲解如何基于activepieces/pieces-common的httpClient编写集成Piece覆盖 GET/POST/Bearer/Basic 认证、通用 API 封装、分页拉取、createCustomApiCallAction与错误处理。无论你要新建一个集成还是为现有 Piece 新增 Action / Trigger这些模式都是连接第三方 REST API 的公共地基。读完本文你将能独立写出一套结构清晰、可复用、经得起 Code Review 的 Piece 代码并能在 github 集成 与 stripe 集成 的真实实现中找到对应佐证。为什么一切 API 调用都要走 httpClient在 Activepieces 生态里Piece 代码运行在服务端执行引擎中所有对外 HTTP 请求都必须经由activepieces/pieces-common提供的httpClient统一发送而不是直接使用fetch或axios。这样做的好处是认证信息统一封装、请求/响应结构与类型安全一致、并自动融入平台的执行与错误处理链路。import { httpClient, HttpMethod, AuthenticationType } from activepieces/pieces-common;HttpMethod枚举定义在 packages/pieces/common/src/lib/http/core/http-method.ts支持GET / POST / PATCH / PUT / DELETE / HEADAuthenticationType定义在 packages/pieces/common/src/lib/authentication/index.ts目前提供BEARER_TOKEN与BASIC两种认证类型。调用sendRequestT后返回的HttpResponseT上可直接读取response.body已按泛型 T 解析、response.status与response.headers。五种最常用的请求形态GET with Bearer TokenAPI Key / Token 类认证是集成开发中最常见的场景通过authentication字段声明即可无需手拼 Headerconst response await httpClient.sendRequest{ data: Item[] }({ method: HttpMethod.GET, url: https://api.example.com/v1/records, authentication: { type: AuthenticationType.BEARER_TOKEN, token: apiKey, }, queryParams: { limit: 100, page: 1 }, }); // response.body, response.status, response.headersqueryParams的值统一为字符串方便直接透传响应体类型通过泛型{ data: Item[] }指定让后续response.body.data具备完整类型推断。POST with Body创建类操作在 GET 的基础上增加body字段框架会按 JSON 请求体发送const response await httpClient.sendRequest({ method: HttpMethod.POST, url: https://api.example.com/v1/records, authentication: { type: AuthenticationType.BEARER_TOKEN, token: apiKey, }, body: { name: New Record, status: active }, });注意有些 API如 Stripe 的 x-www-form-urlencoded 表单需要特殊 Content-Type此时应显式传入headers见下文。Basic Auth用户名 密码式认证使用AuthenticationType.BASICconst response await httpClient.sendRequest({ method: HttpMethod.GET, url: https://api.example.com/v1/records, authentication: { type: AuthenticationType.BASIC, username: user, password: pass, }, });Custom Headers不使用认证助手当目标 API 需要自定义 Header、或多重认证头如签名头时可以直接用headers覆盖const response await httpClient.sendRequest({ method: HttpMethod.GET, url: https://api.example.com/v1/records, headers: { Authorization: Bearer ${apiKey}, X-Custom-Header: value, }, });这是逃生舱一般仅在认证助手表达不了需求时才用能走authentication就尽量走authentication。Common API Helper Pattern集中管理 API 逻辑当一个 Piece 有多个 Action 共享同一套 API 调用逻辑相同的 Base URL、认证方式、路径拼接时应在src/lib/common/index.ts中集中封装避免每个 Action 里重复拼 URL 与认证。目录结构约定可参考 piece-builder 的 SKILL.md 中的 scaffold 部分src/lib/下分别放auth.ts、actions/、triggers/与可选的common/。import { httpClient, HttpMethod, AuthenticationType, HttpMessageBody, HttpResponse, } from activepieces/pieces-common; import { Property } from activepieces/pieces-framework; import { myAppAuth } from ../auth; const BASE_URL https://api.example.com/v1; // Centralized API call function export async function myAppApiCallT extends HttpMessageBody({ token, method, path, body, queryParams, }: { token: string; method: HttpMethod; path: string; body?: unknown; queryParams?: Recordstring, string; }): PromiseHttpResponseT { return await httpClient.sendRequestT({ method, url: ${BASE_URL}${path}, authentication: { type: AuthenticationType.BEARER_TOKEN, token, }, queryParams, body, }); } // Reusable dropdown definitions export const myAppCommon { projectDropdown: Property.Dropdown({ displayName: Project, auth: myAppAuth, refreshers: [], required: true, options: async ({ auth }) { if (!auth) { return { disabled: true, options: [], placeholder: Connect your account first }; } const response await myAppApiCall{ data: { id: string; name: string }[] }({ token: auth.secret_text, // typed automatically because auth: myAppAuth is set above — no cast method: HttpMethod.GET, path: /projects, }); return { disabled: false, options: response.body.data.map((p) ({ label: p.name, value: p.id, })), }; }, }), };这段封装里有三个关键设计泛型贯穿myAppApiCallT extends HttpMessageBody把响应体类型从调用处一路透传到HttpResponseT类型安全不打折。Dropdown 复用把项目下拉框这类高频 prop 定义成myAppCommon.projectDropdown各 Action 直接引用避免复制粘贴。零 cast 的类型推导只要在Property.Dropdown上声明auth: myAppAuth回调参数auth就会被自动推导为对应连接类型auth.secret_text直接可用。然后在 Action 中使用import { myAppCommon, myAppApiCall } from ../common; import { myAppAuth } from ../auth; export const listTasksAction createAction({ auth: myAppAuth, name: list_tasks, displayName: List Tasks, description: Lists tasks in a project, props: { project: myAppCommon.projectDropdown, // Reuse the dropdown }, async run(context) { const response await myAppApiCall{ data: any[] }({ token: context.auth.secret_text, method: HttpMethod.GET, path: /projects/${context.propsValue.project}/tasks, }); return response.body; }, });注意context.auth.secret_textSecretText类型的连接在运行期解析出的就是{ secret_text }对象而不是裸字符串认证访问模式速查表可参见 SKILL.md 的 Quick Auth Reference。仓库中的真实范例GitHub 集成packages/pieces/community/github/src/lib/common/index.ts 定义了githubCommon其中repositoryDropdown、milestoneDropdown、branchDropdown、issueDropdown等全部是复用型 Dropdown并导出了githubApiCall统一封装第 479-510 行。Stripe 集成packages/pieces/community/stripe/src/lib/common/index.ts 的stripeCommon内置invoice、customer、product、price、subscription、payout、paymentIntent、paymentLink等全套业务下拉框并且customer/product/price下拉框还支持searchValue走搜索端点第 127-179 行。Pagination Helper Pattern分页拉取的通用写法对返回分页结果的 API逐个 Action 手写翻页逻辑容易出错。建议封装一个分页辅助函数以page翻页、固定per_page 100用响应里的has_more标记控制循环export async function myAppPaginatedApiCallT({ token, method, path, queryParams, }: { token: string; method: HttpMethod; path: string; queryParams?: Recordstring, string | number; }): PromiseT[] { const results: T[] []; let page 1; const perPage 100; let hasMore true; while (hasMore) { const response await myAppApiCall{ data: T[]; has_more: boolean }({ token, method, path, queryParams: { ...queryParams, page: String(page), per_page: String(perPage), } as Recordstring, string, }); results.push(...response.body.data); hasMore response.body.has_more; page; } return results; }真实范例GitHub 集成的 githubPaginatedApiCall 给出了一个更贴近实战的变体——它不依赖响应体里的has_more字段而是解析 GitHub REST API 标准的Link响应头relnext来判断是否还有下一页同时支持可选的extractItems回调用于{ total_count, workflows }这类包装结构见 getWorkflows。翻页循环内部用do...while保证至少请求一次并用qs.page qs.page 1递增。这种读 Link 头的模式比固定分页字段更通用值得借鉴。Custom API Call Action给高级用户留一扇门每个 Piece 都应该提供createCustomApiCallAction——它自动生成一个通用的自定义 API 调用Action让高级用户在不改代码的前提下调用该集成的任意端点这是 Power User 的刚需import { createCustomApiCallAction } from activepieces/pieces-common; // In createPiece actions array: createCustomApiCallAction({ baseUrl: () https://api.example.com/v1, auth: myAppAuth, // auth is the connection object — read auth.secret_text (SecretText), not bare ${auth}. authMapping: async (auth) ({ Authorization: Bearer ${auth.secret_text}, }), })createCustomApiCallAction的实现位于 packages/pieces/common/src/lib/helpers/index.ts从第 120 行起包含 base URL 拼接、默认说明生成等逻辑它负责把baseUrl与用户填写的相对路径安全拼接、执行认证映射、并对二进制响应做 content-type → 文件扩展名推断最终产出可直接落盘的文件输出。两个必须注意的坑认证映射读取的是连接对象。SecretText类型要读auth.secret_text不能把auth整个当字符串拼进 Header。OAuth2 的写法不同auth由auth: myAppAuth自动推导为 OAuth2 连接类型直接读auth.access_tokencreateCustomApiCallAction({ baseUrl: () https://api.example.com, auth: myAppAuth, authMapping: async (auth) ({ Authorization: Bearer ${auth.access_token}, }), })同时别忘记在createPiece的actions: [...]数组中挂载它SKILL.md 的 Quick Piece Definition Template 中展示了完整写法。Error Handling错误处理的两套姿势在 Action 的 run() 中run()里抛出的错误会自动展示给最终用户。为了让错误信息更可读建议捕获原始异常并补充业务上下文后重新抛出async run(context) { try { const response await httpClient.sendRequest({ /* ... */ }); return response.body; } catch (error) { throw new Error(Failed to create record: ${(error as Error).message}); } }在 Dropdown 的 options 中Dropdown 回调不能抛错会导致下拉框直接打不开正确的做法是返回禁用态 占位提示options: async ({ auth }) { if (!auth) { return { disabled: true, options: [], placeholder: Connect your account first }; } try { const response await httpClient.sendRequest({ /* ... */ }); return { disabled: false, options: [...] }; } catch (error) { return { disabled: true, options: [], placeholder: Failed to load options. Check connection. }; } }这一约定在 Stripe 集成中有大量实例例如 stripeCommon.invoice 未连接时返回Please connect your Stripe account first拉取失败时返回Error loading invoices. Check connection.GitHub 的repositoryDropdown未认证时返回please authenticate firstpackages/pieces/community/github/src/lib/common/index.ts#L25-L32。所有返回的占位文案都面向非技术用户这也是 SKILL.md 中 UX Quality 章节 的明确要求。落地清单把这些模式组合进真实 Piece把这套 Common Patterns 应用到实际集成开发时建议按 piece-builder 工作流 的 Step 4/5 收尾在src/lib/common/index.ts集中放置myAppApiCall或直接复刻 GitHub 的githubApiCall封装风格高频实体项目、客户、产品用Property.Dropdown封装成myAppCommon对象有分页的端点用 Pagination Helper 收敛翻页逻辑在createPiece的actions里追加createCustomApiCallAction并正确区分secret_text与access_token所有 Dropdown 的options回调保证未认证 / 请求失败两条路径都返回禁用态别忘了在src/index.ts导入全部 Action/Trigger 并注册到tsconfig.base.json随后执行npx turbo run build --filteractivepieces/piece-name与npx turbo run lint --filteractivepieces/piece-name验证。遵循这些模式写出来的 Piece既有统一的类型安全与认证处理又让新增一个 Action变成纯增量工作——这正是 Activepieces 社区 400 集成能够保持一致质量的基础。【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价