Closed dferber90 closed 6 years ago
Thanks for this @dferber90. Looks very interesting to me. As this data shape is currently a specific requirement of the MC, I don't know if it's a good idea to add this package to the SDK. Especially because with regards to data shape, any other use for the SDK may then require a different data shape.
@wizzy25 Normalisation is not something specific to the MC. It's widely used best practice to normalise data.
For example from the redux documentation: https://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
@dferber90 My comment was referring to the schema used in your branch/package and not to normalisation in general
Oh, sorry I misunderstood that!
The schema normalises based on the reference expansions points our API provides. That seems like the ideal place to normalise data, doesn't it?
We're still discussing on whether we want to move forward with this in the MC internally. I definitely don't want to push us to implement this if we don't even use it ourselves and nobody asks for it.
Anyways, this is more or less on hold until we align within the MC. I can close and come back later in case we still want this.
Description
The MC currently normalises some data received through the API. This normalisation happens through normalizr.
However, we assume that normalisation may be useful for everybody, so it should be included in this toolkit.
Example implementation
I went ahead and created an example implementation for responses of
/products
and/products/:id
on this branch.We would need to implement the schemas behind the remaining endpoints. This is quite straightforward, it just takes a bit of time. I didn't implement more yet as I wanted to get feedback first.
Examples
Open them (long)
#### Querying a single product When querying `/product/:id` we receive a product of the following shape ```js { "id": "product-id-1", "productType": { "obj": { "id": "product-type-id-1" } }, "masterData": { "current": { "categories": [ { "obj": { "id": "category-id-1" } }, { "obj": { "id": "category-id-2" } } ], "masterVariant": { "prices": [ { "customerGroup": { "obj": { "id": "customer-group-id-1" } }, "channel": { "obj": { "id": "channel-id-2", "custom": { "type": { "obj": { "id": "custom-id-1" } } } } }, "discounted": { "discount": { "obj": { "id": "product-discount-id-1" } } }, "custom": { "type": { "obj": { "id": "custom-id-2" } } } } ], "assets": [ { "custom": { "type": { "obj": { "id": "custom-id-2" } } } } ], "scopedPrice": { "customerGroup": { "obj": { "id": "customer-group-id-2" } }, "channel": { "obj": { "id": "channel-id-1", "custom": { "type": { "obj": { "id": "custom-id-2" } } } } }, "discounted": { "discount": { "obj": { "id": "product-discount-id-1" } } }, "custom": { "type": { "obj": { "id": "custom-id-3" } } } } }, "variants": [ { "prices": [ { "customerGroup": { "obj": { "id": "customer-group-id-1" } }, "channel": { "obj": { "id": "channel-id-1", "custom": { "type": { "obj": { "id": "custom-id-1" } } } } }, "discounted": { "discount": { "obj": { "id": "product-discount-id-1" } } }, "custom": { "type": { "obj": { "id": "custom-id-2" } } } } ], "assets": [ { "custom": { "type": { "obj": { "id": "custom-id-2" } } } } ], "scopedPrice": { "customerGroup": { "obj": { "id": "customer-group-id-2" } }, "channel": { "obj": { "id": "channel-id-2", "custom": { "type": { "obj": { "id": "custom-id-2" } } } } }, "discounted": { "discount": { "obj": { "id": "product-discount-id-1" } } }, "custom": { "type": { "obj": { "id": "custom-id-3" } } } } } ] } } } ``` After normalisation the response will be normalised to ```js { "entities": { "categories": { "category-id-1": { "id": "category-id-1", }, "category-id-2": { "id": "category-id-2", }, }, "channels": { "channel-id-1": { "custom": { "type": { "obj": "custom-id-1", }, }, "id": "channel-id-1", }, "channel-id-2": { "custom": { "type": { "obj": "custom-id-2", }, }, "id": "channel-id-2", }, }, "customerGroups": { "customer-group-id-1": { "id": "customer-group-id-1", }, "customer-group-id-2": { "id": "customer-group-id-2", }, }, "productDiscounts": { "product-discount-id-1": { "id": "product-discount-id-1", }, }, "productTypes": { "product-type-id-1": { "id": "product-type-id-1", }, }, "products": { "product-id-1": { "id": "product-id-1", "masterData": { "current": { "categories": [ { "obj": "category-id-1", }, { "obj": "category-id-2", }, ], "masterVariant": { "assets": [ { "custom": { "type": { "obj": "custom-id-2", }, }, }, ], "prices": [ { "channel": { "obj": "channel-id-2", }, "custom": { "type": { "obj": "custom-id-2", }, }, "customerGroup": { "obj": "customer-group-id-1", }, "discounted": { "discount": { "obj": "product-discount-id-1", }, }, }, ], "scopedPrice": { "channel": { "obj": "channel-id-1", }, "custom": { "type": { "obj": "custom-id-3", }, }, "customerGroup": { "obj": "customer-group-id-2", }, "discounted": { "discount": { "obj": "product-discount-id-1", }, }, }, }, "variants": [ { "assets": [ { "custom": { "type": { "obj": "custom-id-2", }, }, }, ], "prices": [ { "channel": { "obj": "channel-id-1", }, "custom": { "type": { "obj": "custom-id-2", }, }, "customerGroup": { "obj": "customer-group-id-1", }, "discounted": { "discount": { "obj": "product-discount-id-1", }, }, }, ], "scopedPrice": { "channel": { "obj": "channel-id-2", }, "custom": { "type": { "obj": "custom-id-3", }, }, "customerGroup": { "obj": "customer-group-id-2", }, "discounted": { "discount": { "obj": "product-discount-id-1", }, }, }, }, ], }, }, "productType": { "obj": "product-type-id-1", }, }, }, "types": { "custom-id-1": { "id": "custom-id-1", }, "custom-id-2": { "id": "custom-id-2", }, "custom-id-3": { "id": "custom-id-3", }, }, }, "result": "product-id-1", } ``` #### Querying multiple products When querying `/products` Original Response ```js { limit: 5, offset: 0, count: 2, total: 2, results: [{ id: 'product-a' /* ... */ }, { id: 'product-b' /* ... */ }], } ``` After normalising ```js { entities: { products: { 'product-a': {/* ... */}, 'product-b': {/* ... */}, }, // ... }, result: { limit: 5, offset: 0, count: 2, total: 2, results: ['product-a', 'product-b'], } } ```Future
Pro / Con
Pros of normalised data
Cons of normalised data
Overall I'm not sure whether we should continue with this or not. I'll kickstart a discussion within the MC.