mcpField
C
commerce-app-api-mesh

commerce-app-api-mesh

github.com/adobe开发316130 次安装今天更新
代码仓库

关于 commerce-app-api-mesh

commerce-app-api-mesh 是通过 Adobe API Mesh 将 Commerce GraphQL API 与运行时操作组合起来的技能。它指导开发者配置数据源、用委托解析器扩展类型,并部署和验证网格。

主要功能

  1. 01配置 GraphQL 和 OpenAPI 数据源
  2. 02将运行时操作公开为网格数据源
  3. 03用解析器扩展 Commerce 类型
  4. 04部署并验证网格变更
  5. 05检查认证、嵌套及浏览器请求

适用场景

  1. 01为 Commerce 类型添加运行时操作字段
  2. 02让应用连接经过认证的 Commerce 数据
  3. 03验证浏览器对已部署网格的访问

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/adobe/skills --skill commerce-app-api-mesh

安装后在 Claude Code 中输入/commerce-app-api-mesh确认已加载。

详细介绍

在 Commerce 应用前方接入 API Mesh

将 Commerce 自身的 GraphQL API 与此应用的运行时操作组合成一个网格架构。本技能涵盖两种操作:将运行时操作公开为网格源,以及扩展现有 Commerce 类型,添加一个通过委托给该源来解析的字段。

本技能假定你已掌握 API Mesh 的通用知识(mesh.json 的结构、处理程序类型、转换、钩子、密钥、CORS、通用声明式/编程式解析器)。如果你对其中任何内容不熟悉,请先从 Adobe 的官方资料中了解相关知识——参见参考资料——不要自行猜测语法。这些资料都没有介绍如何通过 additionalResolvers(targetTypeName/sourceTypeName/requiredSelectionSet/sourceSelectionSet)扩展现有 Commerce 类型,也没有介绍如何将 aio-commerce-sdk 运行时操作封装为网格源——以下内容将介绍这两点。

前置条件

  • 已安装 aio plugins install @adobe/aio-cli-plugin-api-mesh。
  • 如果要将运行时操作公开为源,该操作已构建并部署,且具有可访问的 HTTPS 端点——指向未部署操作的源会以不明原因失败。
  • 检查此工作区是否已有网格:aio api-mesh:get。如果显示“未找到网格”,则使用 create;否则,你是在编辑现有的 mesh.json,应使用 update。

步骤 1 — 通过内省确认架构形状

在编写 additionalTypeDefs 或 additionalResolvers 之前,请对要扩展的 Commerce(或其他)GraphQL 源进行内省。不要凭记忆或类似的命名惯例假设类型/字段名称——名称稍有出入,就可能导致网格构建成功,但解析器始终不会触发。

curl -s -X POST "<graphql-endpoint>" -H "Content-Type: application/json" \
  -d '{"query":"{ __type(name: \"<TargetType>\") { fields { name } } }"}'

步骤 2 — 搭建源

{
  "name": "Commerce",
  "handler": {
    "graphql": {
      "endpoint": "<commerce-graphql-endpoint>",
      "operationHeaders": { "Authorization": "{context.headers.authorization}" }
    }
  }
}

默认情况下,对于架构包含客户、购物车或会话范围字段的任何源,都应包含 operationHeaders——API Mesh 不会自动转发调用方的 Authorization 标头。省略它会导致每个经过身份验证的查询都因后端返回通用的“未授权”错误而失败,这种错误与无效令牌导致的错误无法区分。

要封装运行时操作,请编写一个仅描述其端点的静态 OpenAPI 文档,并通过相对路径引用该文档:

{
  "name": "<SourceName>",
  "handler": { "openapi": { "source": "./mesh/<source>.json" } }
}

OpenAPI 文档本身必须包含足够的结构,让网格能够据此生成 Query 字段——不能只有上面的引用。以下是单个端点运行时操作的最简示例:

{
  "openapi": "3.0.0",
  "info": { "title": "<SourceName>", "version": "1.0.0" },
  "servers": [{ "url": "<runtime-action-base-url>" }],
  "paths": {
    "/<action-path>": {
      "get": {
        "operationId": "<sourceField>",
        "parameters": [
          {
            "name": "<arg>",
            "in": "query",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "<resultField>": { "type": "string" } }
                }
              }
            }
          }
        }
      }
    }
  }
}

operationId 会成为 Query 字段名——它必须与步骤 3 解析器中的 sourceFieldName 完全一致,否则解析器虽然能成功构建,却永远不会触发。

声明的响应架构必须与操作实际返回的内容一致——网格会按照声明解析数据,不会对数据进行重塑。

步骤 3 — 扩展类型并连接解析器

"additionalTypeDefs": "extend type <TargetType> { <newField>: String }",
"additionalResolvers": [
  {
    "targetTypeName": "<TargetType>",
    "targetFieldName": "<newField>",
    "sourceName": "<SourceName>",
    "sourceTypeName": "Query",
    "sourceFieldName": "<sourceField>",
    "requiredSelectionSet": "{ <keyField> }",
    "sourceArgs": { "<arg>": "{root.<keyField>}" },
    "sourceSelectionSet": "{ <resultField> }",
    "result": "<resultField>"
  }
]

从返回对象的源字段中提取标量时,始终将 sourceSelectionSet 与 result 配对使用,切勿单独使用 result。仅使用 result 的路径会手动构建选择集,而不是通过 GraphQL 解析器构建;当目标字段在列表内解析时(例如父级的 items[].<newField>),会因 "No type was found for field node ... __typename" 错误而失败。即使存在此错误,直接从根查询调用相同的源字段也会成功,因此仅凭这项测试不足以证明解析器有效。

第 4 步 — 部署并验证

如果你已经知道基于浏览器的应用会调用此网格,请在首次部署前决定 responseConfig.CORS 的配置 — 下方的浏览器验证层级旨在发现遗漏的 CORS 配置,但提前决定可避免再次部署。

会话中首次调用 aio api-mesh:* 时,会打开交互式浏览器登录(Waiting for browser login...)。无法访问浏览器的 Agent 无法自行完成此操作 — 请将打印出的登录 URI 发给人工,并等待其完成。

aio api-mesh:create mesh.json -c   # first time
aio api-mesh:update mesh.json -c   # subsequent edits

-c/--autoConfirmAction 会跳过交互式提示 Are you sure you want to update the mesh: <id>?。该提示是修改其他人或系统可能已依赖的网格前的唯一检查点 — 仅对你刚创建的、限定在工作区范围内的网格使用 -c(例如在 CI 中,或临时开发工作区中)。更新现有网格、共享网格或已部署的网格时,请省略 -c 并由人工确认提示,或至少在运行命令前取得人工对差异的明确批准 — 请将此视为与任何其他线上基础设施变更相同的操作,而不是例行的 CLI 调用。

配置过程是异步的 — 请轮询,而不要假定已完成:

until aio api-mesh:status 2>&1 | grep -qi success; do sleep 20; done

分两个层级进行验证:先直接验证源的根字段,再验证其真实的嵌套/已认证形式中的字段(使用真实调用方凭据执行列表嵌套查询,而不是平面的根字段调用)。第 1 层通过并不能证明第 2 层可用 — 上述错误在第 1 层中无法发现。

如果使用方应用会直接从浏览器调用此网格(而不只是服务端到服务端调用),请增加第 3 层:从该应用的实际源发起真实请求。上述两个层级只能证明服务端可访问性 — 如果网格没有为该源配置 responseConfig.CORS 条目,这两个层级仍会通过,但经由该网格的所有浏览器调用都会失败,不只是对新字段的调用(请参阅下文 api-mesh-starter-kit 参考资料中的 CORS 部分)。

常见问题

  • 已认证查询出现 "not authorized",即使令牌有效 — 源的 graphql 处理程序缺少 operationHeaders。请检查 mesh.json,而不是令牌。
  • 嵌套/列表字段出现 "No type was found for field node ... __typename",但源的根字段运行正常 — 解析器使用了 result,却没有 sourceSelectionSet。请添加它。

质量标准

  • aio api-mesh:status 报告成功,并且新字段在其真实的嵌套/已认证形式中正确解析,而不只是在源的根字段中。
  • 如果基于浏览器的应用会调用此网格,该应用可以对其完成真实请求 — 而不只是运行 aio api-mesh:status 和 curl。

后续调用

  • 该源尚不存在于运行时操作中 — 先调用 commerce-app-storage、commerce-app-webhooks 或 commerce-app-eventing 来搭建并部署它。

参考资料

  • API Mesh 提示词指南 — Adobe 自己关于如何提示 Agent 编写网格配置的指南;介绍通用工作流和预期
  • api-mesh-starter-kit llm.txt — 参考知识库,涵盖 mesh.json 结构、全部三种处理程序类型、转换、钩子、密钥、上下文状态、CORS 和 CLI 命令集

评论

支持 Markdown