@acromedia/gesso-shopware-middleware
Server-side Gesso API-middleware provider for Shopware 6. It implements the
Provider contract from @acromedia/gesso-api-middleware and routes
/api/middleware/shopware/{action} to Shopware's REST Store API
(/store-api) and, for elevated operations, its Admin API (/api).
It is the server-side companion to the browser-side @acromedia/gesso-shopware
commerce plugin: anything that needs a secret (the Admin API client credentials)
or a privileged lookup lives here, not in the bundle that ships to the browser.
Routing
slug[0] is the provider key (shopware); slug[1] is the action.
| Action | API | Endpoint(s) | Auth |
|---|---|---|---|
address | Store API | /store-api/account/address | sw-access-key + sw-context-token |
customer | Store API | /store-api/account/customer, change-profile | sw-access-key + sw-context-token |
orders | Store API | /store-api/order | sw-access-key + sw-context-token |
customers | Admin API | /api/search/customer | OAuth2 client_credentials bearer |
payments | Admin API | /api/search/payment-method | OAuth2 client_credentials bearer |
Storefront, customer-scoped actions (address, customer, orders) read the
logged-in customer's sw-context-token from the next-auth session JWT (a
forwarded sw-context-token request header is honoured as a fallback). Shopware
rotates that token on stateful calls; the provider echoes the rotated value back
in an sw-context-token response header so the client can persist it.
The admin-scoped actions (customers, payments) never touch the customer
session — they authenticate the integration itself via the Admin API OAuth2
client_credentials grant.
Transport client (SW-0a outcome)
This package uses the official
@shopware/api-client SDK
(pinned to an exact version) as a thin proxy for both APIs, wrapped in
src/rest.ts:
storeClient()builds a per-requestcreateAPIClient— sets the sales-channelsw-access-key, seeds the customer'ssw-context-token, and reports the rotated token through the config'sonContextChangedcallback (backed by the SDK'sonContextChangedhook). This mirrors how@acromedia/gesso-shopwarewraps the same SDK.adminClient()builds acreateAdminAPIClientwith aclient_credentialsgrant. The SDK performsPOST /api/oauth/token, attaches theAuthorization: Bearer …header, and refreshes automatically once the bearer (expires_in, ≈ 600 s) lapses. A single memoized client per host + integration id keeps the token cached across requests, staying within Shopware SaaS'sPOST /api/oauth/tokenrate limit (10/min).
SW-0a spike result: @shopware/api-client was validated for this package's
build and is used directly (no typed-fetch fallback was needed):
- ESM/transpile — it builds cleanly through this package's dual ESM + CJS
tsuppipeline (pnpm --filter @acromedia/gesso-shopware-middleware build). - Token forwarding — the MSW suite (
src/rest.test.ts) asserts the sales-channelsw-access-key, the rotatedsw-context-token, and the adminAuthorization: Bearerheader are all forwarded on the wire, and that the admin token is cached and refreshed on expiry. None of this needs a live store.
Configuration
Read from the environment (see example.env):
| Env var | Purpose |
|---|---|
NEXT_PUBLIC_SHOPWARE_STOREFRONT_URL | Base host of the store. Store API and Admin API both live under it. |
GESSO_SHOPWARE_ACCESS_KEY | Sales-channel access key, sent as sw-access-key (Store API). |
GESSO_SHOPWARE_ADMIN_CLIENT_ID | Admin API integration id (OAuth client_credentials). Server-only. |
GESSO_SHOPWARE_ADMIN_CLIENT_SECRET | Admin API integration secret. Server-only. |
GESSO_JWT_SECRET | next-auth secret used to read the storefront session JWT. |
NEXT_PUBLIC_SHOPWARE_ACCESS_KEY is accepted as a fallback for the access key so
a single value can be shared with the browser-side @acromedia/gesso-shopware
plugin. See the Shopware SaaS provisioning runbook (in the repo root) for how to
obtain each credential.
Usage
Register the provider with the Gesso API middleware in a Next.js catch-all route
(pages/api/middleware/[...slug].ts):
import GessoAPIMiddleware from '@acromedia/gesso-api-middleware';
import shopware from '@acromedia/gesso-shopware-middleware';
export default GessoAPIMiddleware({ shopware });
Development
pnpm --filter @acromedia/gesso-shopware-middleware type-check
pnpm --filter @acromedia/gesso-shopware-middleware lint
pnpm --filter @acromedia/gesso-shopware-middleware test # Vitest + MSW
pnpm --filter @acromedia/gesso-shopware-middleware build # tsup → dist + tarball
The test suite is Vitest + MSW; every Shopware response is mocked, so no live
store is required. Set LIVE_TESTS=true (with the env vars above pointing at a
real store) to disable the mocks.
References
- Store API reference: https://shopware.stoplight.io/docs/store-api
- Admin API concept: https://developer.shopware.com/docs/concepts/api/admin-api.html
- Admin API authentication (
client_credentials): https://developer.shopware.com/docs/guides/development/integrations-api/auth-api-requests.html - Request headers (
sw-access-key,sw-context-token): https://developer.shopware.com/docs/guides/integrations-api/general-concepts/request-headers.html