A later invocation of an OrderInterceptor-like concept
Opened this issue · 3 comments
Is your feature request related to a problem? Please describe.
Currently, the OrderInterceptor
allows implementors to run checks before order mutations are committed. However, the willAddItemToOrder
function does not have visibility into the Order
nor OrderLine
.
Describe the solution you'd like
Introduce a new function, similar to willAddItemToOrder
, that runs at a later stage of the process, after an item has been added to the order (but not yet committed). This function should:
- Provide access to the
OrderLine
with a validid
within the current context. - Allow implementors to reject the mutation by returning a string, throwing an error, or using a similar mechanism.
- Trigger a rollback of the transaction if the mutation is rejected.
This additional functionality would enable more complex validations and use cases by allowing checks based on the newly added OrderLine
.
Describe alternatives you've considered
We initially implemented a bundle-like concept by overriding Shop API mutations. This approach gave us access to the Order
(via activeOrder
) and the bundle's OrderLine
, allowing us to manage relationships between bundle products and their child items. However, this solution is limited to the Shop API and does not leverage OrderInterceptor
functionality.
We also considered extending this approach to the Admin API by overriding draft mutations, aiming for a solution where both Shop API and Admin API would implicitly handle child items. However, after learning about OrderInterceptor
s, we paused our implementation to explore whether they could provide an alternative.
Additional context
In our current implementation of bundles:
- We tie child items to their parent (the bundle product).
- The relative quantities of child items are maintained by noting how many are required for a single bundle and scaling accordingly (e.g., after
add
,adjust
, orremove
operations). - We reject shop-api attempts to mutate the child items directly.
- The proposed enhancement to
OrderInterceptor
could make our implementation more clear and maintainable.
Hi,
Thanks for the good feedback on this new API!
I'm wondering whether we can just keep the existing API but invoke it later:
We would need to wrap the getOrCreateOrderLine()
call in a transaction and manually roll back in the case that the interceptor returns an error.
Would you be interested in testing this out on your use-case and seeing if it is a viable approach?
Yes, I am interested.
One thought though: in this new flow OrderLine
would exist in the OrderInterceptor's willAddItemToOrder
func. Which is great. So I can call getExistingOrderLine
or getOrCreate and expect a non-undefined. But, that means, in effect getExistingOrderLine
would be called. Each call to getExisting is a loop over order.lines
, and looks like an async check to compare customFields. I'm not sure how heavy that bit could be (I didn't spelunk deeper, but I suspect the custom fields comparison does some DB checks?).
If that custom field check is considered heavy, I propose two options:
- amend
WillAddItemToOrderInput
and add OrderLine in there. As well as moving it as you suggest. - or, a new optional func on the OrderInterceptor
- something like
willAddLineItemToOrder
- with its own input interface
WillAddLineItemToOrderInput
which is basically the original addItem version, plusOrderLine
.
- something like
I think either version could land exactly where you pointed to, @michaelbromley.
Hi @michaelbromley, I might have a related issue. Here's a high-level summary:
I use resolvers to override the addition flow:
- The caller invokes the flow with a variantId for a bundle.
- The resolver detects it’s a bundle and:
- Calls service.add(bundle-parent).
- Loops through service.add(bundle-child).
This works.
I attempted a similar flow using OrderInterceptors for adjustOrderLine, but it’s not handling adjustments as expected. While both bundle-parent (triggered by the user) and bundle-children (triggered within my interceptor) hit my interceptor, only the bundle-parent gets adjusted. All my interceptors return
successfully (no strings or exceptions thrown), but the adjustments for bundle-children aren’t applied (most noticeably, the quantity is not adjusted). I tried it by calling the singular and plural versions of adjustOrderLine
, but neither flow returned error response; all flows appeared to signal success. No logs seemed to indicate errors.
Any intuition about what might be going wrong?