These are in a fairly good spot, but we still need a simplified way to communicate product data along with the product display. This will allow clients access to all the information they need to build a product display / Add to Cart form without requiring two separate API requests (one to get the display node data and another to get the actual product data). An example response might be:

{
  nid: 1,
  title: "Laptop Bag 231",
  products: [
    { product_id: 5, sku: "AWEF", price: "$52", images: ["http://example.com/image1.jpg"] }
  ]
}

Where instead of "products" we might use the actual field name of the product reference field (e.g. "field_product"). It might be that we can simply standardize on this behavior for any Drupal Commerce reference field, providing the same behavior for product references, line item references, and customer profile references.

Comments

rszrama’s picture

Status: Active » Fixed

Alrighty - the remaining issue has been addressed, though with a slightly different approach. I realized that it's in our best interest to not destroy the field data, as then the entity can no longer be wrapped or manipulated as expected by the Field API. Much better to simply add a corresponding property to the entity that contains the full entities.

So, I've added a parameter to read requests called expand_entities that defaults to "expanding" the reference field values on the immediate entity into an array of full entities keyed by ID. It only goes to that first depth by default, but you can pass a value greater than 1 to expand the reference field values of child entities as well.

The return value would look more like this:

GET /product-display/1

{
  nid: 1,
  title: "Product One",
  field_product: [ 1 ],
  field_product_entities: {
    1: {
      product_id: 1,
      title: "Product One",
      sku: "PROD-01",
      commerce_price: {
        amount: 1000,
        currency_code: "USD",
        data: { }
      },
      commerce_price_formatted: "$10.00",
      field_size: "Small",
      attribute_fields: [ "field_size" ]
    }
  }
}
}

Note that this is only a subset of the data that would be returned to demonstrate three things:

  1. Notice that the field values in here have been flattened according to #1796946: Provide a way to simplify field data arrays. That feature came in this same patch and basically allows you to return only the field value for the current language of the entity (instead of the full multlingual field value array). For multi-value fields like field_product it still returns an array, and for multi-column fields like commerce_price it still returns an object. However, for a single-value, single-column field like field_size, you'll get the simple scalar value of the field.
  2. Notice then that we have the field_product_entities object that corresponds to the field_product field. Whereas the field value array contains the referenced product IDs, the field_product_entities object contains those fully loaded entities keyed by ID. These referenced entities will also have their fields flattened, and if these referenced products also had product reference fields, you can optionally request those entities to be expanded and so on down the line to whatever depth you require.
  3. Finally, notice that we have a couple special properties on the referenced product. There's commerce_price_formatted, a property that corresponds to commerce_price and contains the formatted price in USD. This association will be made for any price field on any entity - line item, product, order, or even custom price fields on other entities like nodes. Additionally, for product entities you can see there's the attribute_fields property that contains an array of fields on the product that have been configured to function as product attribute fields on Add to Cart forms. This clues clients into how to reproduce an Add to Cart form for a product display that references multiple products. This example doesn't show it, but if there were an image field on the product called field_image, there would be a corresponding property called field_image_url that just contained the full URL to access the image.

I'm up for more ideas along these lines. I'm also considering changing entity expansion to actually use an array, so you can specify what types of entity reference fields should be expanded (along the lines of expand_field_product=1 / expand[field_product]=1 or something similar. I'm not decided. There may be other helper attributes we can decorate entities with - for example, I haven't played around with taxonomy term reference fields at all in relation to these resources yet.

Commit: http://drupalcode.org/project/commerce_services.git/commitdiff/0afd975

sumitk’s picture

Two requests:

  1. We need field_price property outside of field_product_entities. This way users don't have to call field_product_entities each time they are trying to build a product listing.
  2. field_images in GET /product-display is returning no data.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.