feat: Adds support for inserting middleware for operations - #332
Conversation
This allows middleware such as circuit breakers to be inserted and executed during commercetools requests.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #332 +/- ##
=======================================
Coverage 99.32% 99.32%
=======================================
Files 58 58
Lines 1475 1481 +6
Branches 156 158 +2
=======================================
+ Hits 1465 1471 +6
Misses 2 2
Partials 8 8
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds configurable operation middleware around commercetools API request execution.
Changes:
- Defines middleware types and configuration.
- Composes middleware with request execution.
- Passes middleware through API configuration.
- Adds executor and API integration tests.
CommercetoolsAuthApi does not pass configured middleware to its executor, so middleware is skipped for authentication calls. This must be addressed before approval.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Summary |
|---|---|
src/test/request/__tests__/request-executor.test.ts |
Tests middleware behavior. |
src/test/api/CommercetoolsApi.test.ts |
Tests API middleware integration. |
src/lib/types.ts |
Defines middleware configuration and exposes the unresolved auth propagation issue. |
src/lib/request/request-executor.ts |
Composes middleware around requests. |
src/lib/api/types.ts |
Exposes middleware in API configuration. |
src/lib/api/CommercetoolsApi.ts |
Passes middleware to the API executor. |
Suppressed comments (2)
src/lib/api/CommercetoolsApi.ts:331
operationMiddlewaresis now part ofCommercetoolsBaseConfig, so it is accepted byCommercetoolsAuthConfig/CommercetoolsAuthApiConfig, but this only wires it into the API executor.CommercetoolsAuthApistill constructs its executor withoutoperationMiddlewares(src/lib/auth/CommercetoolsAuthApi.ts:46-53), so direct auth calls—and the token request made while preparing an API call—silently bypass the configured middleware. Forward the option in the auth executor as well, or remove it from the shared auth config if authentication is intentionally out of scope.
operationMiddlewares: config.operationMiddlewares,
src/lib/request/request-executor.ts:54
- The new documentation says middleware may call
nextwithout a modified request, butnextis typed asRequestExecutor, whose request argument is required, and this composition forwards the argument directly. A documentednext()call therefore fails type-checking and, at runtime, reachesbaseExecutorwithundefinedand throws when it readsrequestConfig.headers. Make no-argument continuation default to the current request (including the type) or update the contract to requirenext(requestConfig).
const composedExecutor = middlewares.reduceRight<RequestExecutor>((next, middleware) => {
const executor: RequestExecutor = (requestConfig: CommercetoolsRequest) => middleware(next, requestConfig)
return executor
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
src/lib/api/CommercetoolsApi.ts:331
- This only installs the middleware on the API executor, but
CommercetoolsApi.request()callsgetRequestOptions()first and that method may fetch a client grant throughthis.auth;CommercetoolsAuthApialso creates its own executor without forwardingoperationMiddlewares. Consequently auth requests (including the implicit token request before the first API call) bypass a middleware advertised as wrapping a full logical commercetools operation, so a circuit breaker or short-circuit cannot protect those calls. Either apply the same middleware pipeline to the auth executor as well, or narrow the option's documentation and name to explicitly state that it covers API calls only.
operationMiddlewares: config.operationMiddlewares,
src/lib/api/types.ts:18
- This middleware is invoked only after
request()has awaitedgetRequestOptions(), which callsauth.getClientGrant()when no grant is cached. Consequently, an open circuit or other short-circuit still makes the token HTTP request on the first API operation, so the middleware does not actually wrap the full logical operation described here and cannot prevent all outbound calls. Either move token acquisition inside the middleware boundary or scope the option/documentation explicitly to the API request.
* Middleware pipeline that wraps a full logical request operation.
*
* Each middleware receives the next executor in the chain and the request
* config for the current operation. Middleware can:
* - call `next(requestConfig)` to continue,
* - short-circuit by returning a value without calling `next`, or
* - throw to fail the operation.
|
🎉 This PR is included in version 6.30.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This allows middleware such as circuit breakers to be inserted and executed during commercetools requests.