Skip to content

amp-story-shopping JSON Validation I2I #36460

@processprocess

Description

@processprocess

Summary

JSON will be specified inline or fetched from a src attribute.
An inline configuration is required. If src is specified it will override the inline JSON.

To prevent CLS, the experience will render once the request resolves. If the request rejects, the experience will render using the inline config.

Data will be validated by the client at the component-level.
It is validated by the client since the config can be loaded via src.

If any required fields are missing or invalid, no templates will be rendered for the associated product (PDP, product tag, PLP) and a warning will be thrown in the console.

In the case that both src and inline JSON are specified, src will take precedence.

Optional fields that are invalid still will block rendering.
Optional fields that are missing will not block rendering.
Optional fields with required child attributes will block rendering if they are found to be invalid or missing.

isValidConfig = false; should not be set when an optional config field is present && validateRequired is not in the array. I'm adding in some additional checks for this.

JSON

{
   items: [
      {
         productId: "..." // Required. Keys to amp-story-shopping-tag nodes.
         productUrl: "...", // Required. String. Links to the product's website.
         productTitle: "...", // Required. String.
         productPrice: 100, // Required. Number.
         productPriceCurrency: "..." // Required. String. ISO 4217 currency code used to display the correct currency symbol.
         productImages: [ // Required. Array of objects.
            {
               url: "..." // Required. String.
               alt: "..." // Required. String.
            }
         ],
         productDetails: "...", // Required. String.
         aggregateRating: { // Optional. All sub fields are required if defined.
            "ratingValue": 4.4, // Required. Number.
            "reviewCount": 89, // Required. Number.
            "reviewUrl": // Required. String. Links to page where user can read reviews.
         },
         productBrand: "...", // Optional. String.
         productIcon: "...", // Optional. Links to an image. Defaults to a shopping bag icon.
         productTagText: "...", // Optional. String.
      },
      …
   ]
}

A validation config object will store a list of valid attributes. Each entry pairs to an array of validation functions to run against the value.

Validation and the validation config will be contained within the amp-story-shopping-config component.

Validation Config:

const productValidationConfig = {
   'productId': [validateRequired, validateStringLength, validateHTMLId], 
   'productBrand': [validateStringLength],
   'productIcon': [validateURL],
   …
}

Validation Scalability

In future versions of the component, additional fields may be added to render different templates.

For example, a “productDetails” page may be added to pick the size and color of a product. This validation pattern can be expanded to accommodate nested validation configs. In the case that a productDetails entry exists, the productDetailsValidationConfig can be run to check its contents.

Scaled JSON

{
   items: [
      {
         productUrl: "...", // Required. String. Links to the products website.
         productId: "..." // Required. Keys to amp-story-shopping-tag nodes.
         productBrand: "...", // Optional. String.
         productIcon: "...", // Optional. Links to an image. Defaults to a shopping bag icon.
         productTagText: "...", // Optional. String.
         productTitle: "...", // Required. String.
         productPrice: 100, // Required. Number.
         productPriceCurrency: "..." // Required. String. ISO 4217 currency code used to display the correct currency symbol.
         productImages: [ // Required. Must have at least one entry. Array of objects.
            {
               url: "..." // Required. String.
               altText: "..." // Required. String.
            }
         ],
         productDetails: "...", // Required. String.
         aggregateRating: { // Optional. All sub fields are required if defined.. 
            "ratingValue": 4.4, // Required. Number.
            "reviewCount": 89, // Required. Number.
            "reviewUrl": // Required. String. Links to page where user can read reviews.
         }
         productOptions: {
            size: "..." // Required. Array of strings.
            color: "..." // Required. Array of strings.
         }
      },
      …
   ]
}

Scaled Validation Config:

const productValidationConfig = {
    …
   'productOptions': [validateProductOptions]
}

const productOptionsValidationConfig = {
   'size': [validateRequired, validateStringEntries],
   'color': [validateStringEntries]
}

TODO

Investigate using JSON Schema.
Consider SWR (stale-while-revalidate) for caching src data.

Notifications

/cc @ampproject/wg-approvers

Metadata

Metadata

Labels

INTENT TO IMPLEMENTProposes implementation of a significant new feature. https://bit.ly/amp-contribute-codeStaleInactive for one year or moreWG: Caching: TriagedInitial triage from wg-caching complete. Remove label if new input required.WG: stories

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions