We have issues with Drupal Commerce and mixed bundles. I've detailed this https://github.com/mglaman/commerce_cart_api/issues/11.
I had to do some refactoring to support the problem of: Here is a collection of Orders with random bundles, and include their order items.
{
"data": [
{
"type": "commerce_order--physical",
"id": "f4d2360c-c1be-446c-b5b1-717c512e437c",
"attributes": {
"order_id": 1,
"uuid": "f4d2360c-c1be-446c-b5b1-717c512e437c",
"order_number": null,
"total_price": {
"number": "38.000000",
"currency_code": "USD"
}
},
"relationships": {
"store_id": {
"data": {
"type": "commerce_store--online",
"id": "e42f5a27-4ed1-4ebe-8f94-453994077bc0"
},
"links": {
"self": "http:\/\/localhost:32770\/jsonapi\/commerce_order\/physical\/f4d2360c-c1be-446c-b5b1-717c512e437c\/relationships\/store_id",
"related": "http:\/\/localhost:32770\/jsonapi\/commerce_order\/physical\/f4d2360c-c1be-446c-b5b1-717c512e437c\/store_id"
}
},
"order_items": {
"data": [
{
"type": "commerce_order_item--physical_product_variation",
"id": "f170d0f1-deaa-4e26-965c-b53940d04801"
}
],
"links": {
"self": "http:\/\/localhost:32770\/jsonapi\/commerce_order\/physical\/f4d2360c-c1be-446c-b5b1-717c512e437c\/relationships\/order_items",
"related": "http:\/\/localhost:32770\/jsonapi\/commerce_order\/physical\/f4d2360c-c1be-446c-b5b1-717c512e437c\/order_items"
}
}
},
"links": {
"self": "http:\/\/localhost:32770\/jsonapi\/commerce_order\/physical\/f4d2360c-c1be-446c-b5b1-717c512e437c"
}
}
],
"jsonapi": {
"version": "1.0",
"meta": {
"links": {
"self": "http:\/\/jsonapi.org\/format\/1.0\/"
}
}
},
"links": {
"self": "http:\/\/localhost:32770\/jsonapi\/cart?XDEBUG_SESSION_START=1"
},
"included": [
{
"type": "commerce_order_item--physical_product_variation",
"id": "f170d0f1-deaa-4e26-965c-b53940d04801",
"attributes": {
"order_item_id": 1,
"uuid": "f170d0f1-deaa-4e26-965c-b53940d04801",
"title": "24\u0022 x 30\u0022 Hiding Goat Print",
"quantity": "1.00",
"unit_price": {
"number": "38.000000",
"currency_code": "USD"
},
"total_price": {
"number": "38.000000",
"currency_code": "USD"
}
},
"relationships": {
"purchased_entity": {
"data": {
"type": "commerce_product_variation--simple",
"id": "c3d4b09b-8788-46e8-b263-510c5ffe91b5"
},
"links": {
"self": "http:\/\/localhost:32770\/jsonapi\/commerce_order_item\/physical_product_variation\/f170d0f1-deaa-4e26-965c-b53940d04801\/relationships\/purchased_entity",
"related": "http:\/\/localhost:32770\/jsonapi\/commerce_order_item\/physical_product_variation\/f170d0f1-deaa-4e26-965c-b53940d04801\/purchased_entity"
}
}
},
"links": {
"self": "http:\/\/localhost:32770\/jsonapi\/commerce_order_item\/physical_product_variation\/f170d0f1-deaa-4e26-965c-b53940d04801"
}
}
]
}
Comments
Comment #2
mglamanHere is an example patch. The summary is to allow passing a ResourceType to the FieldResolver and then when determining include field info, loop through the FieldMap to find available bundles and field candidates.
Comment #3
mglamanThis is the biggest change. It adjusts the method to re-use the ResourceType gathered from the route.
This allows a ResourceType to have a null bundle and discovered included fields!
Comment #4
mglamanThis breaks \Drupal\jsonapi\Normalizer\FilterNormalizer::expandItem.
EDIT: The
$contextwould need to be updated to contain the ResourceType object.Comment #5
wim leersSorry for the silence! We've been hard at work to get the JSON API 1.x branch done (see https://www.drupal.org/project/jsonapi/releases/8.x-1.22), and to get an update Drupal 8 core patch posted (see #2843147-62: Add JSON:API to core as a stable module).
A week agoTwo weeks ago (I got summoned to help out with other issues, pausing my progress on this comment), the 2.x branch opened, and issues like these are being looked at again :)I first read through https://github.com/mglaman/commerce_cart_api/issues/11. Many of the architectural pain points you refer to have been solved in the mean time:
\Drupal\jsonapi\Context\CurrentContextno longer exists (instead,resource_typeroute default +\Drupal\jsonapi\ParamConverter\ResourceTypeConverter)EntityToJsonApi::calculateContext()no longer exists at allResourceTypeRepository, which I think is the real blocker for your use case.And at least one is in progress:
And finally, one that remains to be done, and needs your input:
This sounds like #2956414: Support mixed-bundle collections (e.g. `/jsonapi/node`). That's the one thing that is definitely not yet supported, but totally could be.
It would be fantastic if you could give https://github.com/mglaman/commerce_cart_api/tree/jsonapi a second chance. I'd be more than willing to jump on a call with you to live debug this, to truly understand where the remaining blockers are, if any.
Comment #6
wim leers#2984911: Remove access to the Request object in the normalization process landed ~2 weeks ago.
@mglaman: Would be great if you could give this another try!
Comment #7
mglaman@Wim, I will try! I did give it a quick look before and I thought I still saw some blockers. But I was busy hurrying up for Decoupled Days, Vacation, and then Drupal Europe. My schedule has simmered down, now. So I'll give it another take!
Comment #8
wim leers🤘
Comment #9
mglamanHoly cow! NULL BUNDLES ARE SUPPORT!
EDIT: This is only one order type with one order item type. It needs testing. But, before, it would not even return this much data. It always had errors.
There's a weird access quirk, but here is the controller: https://github.com/mglaman/commerce_cart_api/blob/jsonapi/src/Controller...
Here's the output for a cart with one item.
Comment #10
mglamanIn talking with @gabesullice, we came up with the following code for a custom controller to return mixed bundles of an entity type (without paging.)
The controller method looks like this:
It dies at \Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber::generateContext, because there is no resource type on the request. Which we can't provide since the bundle needs to be null. But as previously shown, that works fine.
Comment #11
wim leers#9: EXCITING! :D 🎉
#10:
Actually, I think you might've been on an old JSON API 2.x version, because #3000622: Improve EntryPoint::index() now that JsonApiDocumentTopLevel is more capable softened that requirement, since the "entry point" route (
/jsonapi) also doesn't have a resource type.Can you update to the tip of the 2.x branch and check again? 🙏
Comment #12
mglamanI had latest HEAD on 2.x. See #3001564: Follow-up to #2997600: Clean up dead code paths :)
Comment #13
wim leersOhhhh…
It wasn't that
$resource_type = $request->get('resource_type');line that you quoted that caused problems. It was something after that that failed. Would you mind doing a quick round of remote pair programming to step through what's going on? That's probably going the easiest way to resolve this.Comment #14
wim leersBesides #10/#13, there seems to be one other blocker. From the updated README at https://github.com/mglaman/commerce_cart_api/tree/jsonapi:
Can you explain this a bit more? I see that you have some fields being explicitly forbidden access to, probably to omit them from the response. Have you considered marking them "internal"? See https://www.drupal.org/node/2916592. That'd work in both core REST and JSON API (and hopefully soon also in GraphQL).
I really want to make sure that Commerce can do what it needs to do on top of JSON API, since we want to get JSON API into core. It'd be sad if you could benefit from JSON API's much better DX (compared to core REST's) for everything except the Commerce Cart.
Comment #15
wim leersComment #16
wim leersFYI: if you could add a test or even just a test module that sets things up in just the right way, I'd be happy to take it from there. Right now I don't know enough about Drupal Commerce to get everything set up so that I can push this forward myself.
Comment #17
mglamanI have other concerns, which I talked about in the jsonapi channel. I'll have to dig those up, and it's a different thread than this.
After the blocked issue from #12 I could remove that snippet: https://github.com/mglaman/commerce_cart_api/commit/b4a0a11d926ef803e162...
The response comes through fine!
Yeah, this was me using bad terms. This proper way would be to use isInternal or checking admin permissions.
As far as I'm concerned, this issue is now fixed. I'm able to return a collection of entities with mixed bundles without JSON API crashing, via a custom endpoint.
Concerns around limitations and spec problems for the Commerce data model and a Cart API could be carried on in an issue in that project.
Comment #18
wim leers🎉
So the obvious next question then is: what does this mean for https://www.drupal.org/project/commerce_cart_api?
Comment #19
mglaman:) Today and the next few days I will work to open a "2.x" issue for that project, outlining its goals and improvements. I still find some problems around the implementations with JSON API (less on the Drupal implementation, more with the spec.) It will summarize some discussions I had with
gabesullice and my own thoughts.
Comment #20
wim leersLooking forward to reading those!
Comment #21
wim leers@mglaman Any news? :)
Comment #22
wim leersPinged @mglaman: https://twitter.com/wimleers/status/1052488639450636288
Comment #23
wim leersJSON API 2.0 RC1 has been released. Now is the time to ensure that JSON API 2 can do what Commerce needs!
Comment #24
wim leersRC2 was released two days ago. #23 is now even more relevant.
Comment #25
gabesulliceI pinged @mglaman on Slack about this... x-posting the conversation here:
Comment #26
wim leersCan you show through an example how it’s too much work?
Gabe, your hypermedia proposal can probably make a big difference here.
Comment #27
mglamanThis specific issue can be closed. 2.0 allowed me to build a collection with mixed bundles: https://github.com/mglaman/commerce_cart_api/blob/jsonapi/src/Controller...
Anything related to working with JSON API I can open in follow-up issues (#25 touches on other concerns)