Skip to main content

commerce-app-api-mesh

Scaffold or update an Adobe API Mesh configuration (mesh.json) in front of a Commerce app: add GraphQL/OpenAPI sources, extend an existing Commerce GraphQL type with a new field, and wire a cross-source resolver for it. Use when the user mentions API Mesh, mesh.json, extending a Commerce GraphQL type (e.g. adding a field to Order/CustomerOrder/Product), or stitching a runtime action's data into the storefront's GraphQL schema.

インストールへ移動

ソース情報

リポジトリ
adobe/skills
ソースの最終更新活動
2026年9月15日 16:28
検出された SKILL.md の言語
英語
スター
187
フォーク
78

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
commerce-app-api-mesh
description
Scaffold or update an Adobe API Mesh configuration (mesh.json) in front of a Commerce app: add GraphQL/OpenAPI sources, extend an existing Commerce GraphQL type with a new field, and wire a cross-source resolver for it. Use when the user mentions API Mesh, mesh.json, extending a Commerce GraphQL type (e.g. adding a field to Order/CustomerOrder/Product), or stitching a runtime action's data into the storefront's GraphQL schema.
license
Apache-2.0
compatibility
Requires the api-mesh CLI plugin (aio plugins install @adobe/aio-cli-plugin-api-mesh). If wrapping a runtime action as a source, that action must already be built and deployed.
metadata
{"author":"adobe"}
# Wire API Mesh in Front of a Commerce App Composes Commerce's own GraphQL API and this app's runtime actions into a single mesh schema. Two moves this skill covers: exposing a runtime action as a mesh source, and extending an existing Commerce type with a field resolved by delegating to that source. This skill assumes general API Mesh knowledge (`mesh.json` anatomy, handler types, transforms, hooks, secrets, CORS, generic declarative/programmatic resolvers). If any of that is unfamiliar, load it from Adobe's own material first — see [References](#references) — rather than guessing at syntax. None of that material covers extending an existing Commerce type via `additionalResolvers` (`targetTypeName`/`sourceTypeName`/`requiredSelectionSet`/`sourceSelectionSet`) or wrapping an aio-commerce-sdk runtime action as a mesh source — that's what follows. ## Prerequisites - `aio plugins install @adobe/aio-cli-plugin-api-mesh` is installed. - If exposing a runtime action as a source, it's already built and deployed with a real, reachable HTTPS endpoint — a source pointing at an undeployed action fails opaquely. - Check whether a mesh already exists for this workspace: `aio api-mesh:get`. "No mesh found" → you'll `create`; otherwise you're editing an existing `mesh.json` and will `update`. ## Step 1 — Confirm schema shapes via introspection Before writing `additionalTypeDefs` or `additionalResolvers`, introspect the Commerce (or other) GraphQL source you're extending. Don't assume a type/field name from memory or a similar-sounding convention — near-miss names produce a mesh that builds successfully but whose resolver never fires. ```bash curl -s -X POST "<graphql-endpoint>" -H "Content-Type: application/json" \ -d '{"query":"{ __type(name: \"<TargetType>\") { fields { name } } }"}' ``` ## Step 2 — Scaffold sources ```json { "name": "Commerce", "handler": { "graphql": { "endpoint": "<commerce-graphql-endpoint>", "operationHeaders": { "Authorization": "{context.headers.authorization}" } } } } ``` Include `operationHeaders` by default on any source whose schema has customer-, cart-, or session-scoped fields — API Mesh does **not** forward the caller's `Authorization` header automatically. Omitting it makes every authenticated query fail with the backend's own generic "not authorized" error, indistinguishable from an invalid token. To wrap a runtime action, write a small static OpenAPI document describing just its endpoint and reference it by relative path: ```json { "name": "<SourceName>", "handler": { "openapi": { "source": "./mesh/<source>.json" } } } ``` The OpenAPI document itself needs enough shape for the mesh to generate a Query field from it — not just the pointer above. Minimal example for a single-endpoint runtime action: ```json { "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` becomes the Query field name — it must match `sourceFieldName` in Step 3's resolver exactly, or the resolver builds successfully but never fires. The declared response schema must match what the action actually returns — the mesh parses according to what you declare, it doesn't reshape data. ## Step 3 — Extend a type and wire the resolver ```json "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>" } ] ``` Always pair `sourceSelectionSet` with `result` when extracting a scalar from an object-returning source field — never use `result` alone. The `result`-only path builds its selection set by hand instead of via the GraphQL parser, and breaks with `"No type was found for field node ... __typename"` specifically when the target field resolves inside a list (e.g. a parent's `items[].<newField>`). A direct root-query call to the same source field succeeds even when this bug is present, so that test alone isn't sufficient proof the resolver works. ## Step 4 — Deploy and verify If you already know a browser-based app will call this mesh, decide `responseConfig.CORS` now, before your first deploy — the browser-verification tier below exists to catch a missed CORS config, but deciding upfront avoids a second deploy cycle. The first `aio api-mesh:*` call in a session opens an interactive browser login (`Waiting for browser login...`). An agent without browser access can't complete this itself — hand the printed login URI to the human and wait. ```sh aio api-mesh:create mesh.json -c # first time aio api-mesh:update mesh.json -c # subsequent edits ``` `-c`/`--autoConfirmAction` skips the interactive `Are you sure you want to update the mesh: <id>?` prompt. That prompt is the only checkpoint before mutating a mesh other people or systems may already depend on — reserve `-c` for a workspace-scoped mesh you just created yourself (e.g. in CI, or a throwaway dev workspace). When updating an existing, shared, or already-deployed mesh, omit `-c` and have a human confirm the prompt, or at minimum get explicit human sign-off on the diff before running the command — treat this like any other live-infrastructure change, not a routine CLI call. Provisioning is asynchronous — poll rather than assume completion: ```sh until aio api-mesh:status 2>&1 | grep -qi success; do sleep 20; done ``` Verify in two tiers: first the source's root field directly, then the field in its real nested/authenticated shape (a list-nested query with a real caller credential, not a flat root-field call). Tier 1 passing does not prove tier 2 works — the bug above is invisible in tier 1. If the consuming app will call this mesh directly from a browser (not just server-to-server), add a third tier: a real request from that app's actual origin. The two tiers above only prove server-side reachability — a mesh with no `responseConfig.CORS` entry for that origin passes both while still failing every browser call through it, not just the new field (see the CORS section of the api-mesh-starter-kit reference below). ## Common Issues - **`"not authorized"` on an authenticated query, even with a valid token** — the source's `graphql` handler is missing `operationHeaders`. Check `mesh.json`, not the token. - **`"No type was found for field node ... __typename"` on a nested/list field, but the source works fine at root** — the resolver uses `result` without `sourceSelectionSet`. Add it. ## Quality Bar - `aio api-mesh:status` reports success, and the new field resolves correctly in its real nested/authenticated shape, not just at the source's root field. - If a browser-based app will call this mesh, that app can complete a real request against it — not just `aio api-mesh:status` and `curl`. ## Chaining - **The source doesn't exist yet as a runtime action** — invoke `commerce-app-storage`, `commerce-app-webhooks`, or `commerce-app-eventing` to scaffold and deploy it first. ## References - [API Mesh prompting guide](https://developer.adobe.com/graphql-mesh-gateway/mesh/basic/prompting.md) — Adobe's own guidance for prompting an agent to write mesh configs; general workflow and expectations - [api-mesh-starter-kit llm.txt](https://raw.githubusercontent.com/adobe-commerce/api-mesh-starter-kit/refs/heads/main/llm.txt) — reference knowledge base covering `mesh.json` anatomy, all three handler types, transforms, hooks, secrets, context state, CORS, and the CLI command set
GitHubで見る