Regarding: MGNLREST-682 - Getting issue details... STATUS


The reference resolving is a useful and popular feature, but the way it is configured causes problems for developers.

  • Name conflicts: Currently you only supply a property name. It can eaasily happen that multiple content items have the same property name, and you might get things resolved not in the way you intended. For example if you have an "image" property - you might want to handle it differently in different components, but this is not possible.
  • The REST response returns the entire content item, where you might only want a few properties. (Like in a page.)


Ideas


Configure Reference Resolving at the Component instead of the Rest Endpoint

Currently, you configure references on the delivery endpoint. But in the case of Pages Endpoint this is awkward because it means the REST endpoint needs to "know" about the components being used, it needs to anticipate all of the different components that could be on the page. But this is a strange dependency. If you add a new component, then you might need to update the endpoint to match it.

I think it would make more sense to configure any references to expand directly on the component itself. The component includes the rendering, so it would make sense that it could define which properties are references and should be expanded. 

Then the endpoint could "walk the tree" of components and for each component, resolve any references based on the special new configuration on that component. (So it would be working somewhat like the freemarker renderer does.)


How could this be configured?

Lets use example from travel demo of the TourCarousel. Here is the dialog definition.

A tour has an image  and tourTypes .

form:
  properties:
    - name: tours
      $type: jcrMultiValueField
      field:
        $type: linkField
        editable: false
        datasource:
          $type: jcrDatasource
          workspace: tours

In component template definition?

Put the same reference resolver configuration in the component template definition?

Cons:

  • This might still have name conflicts, but they would be scoped much smaller - just to referenced items.

/components/tourCarousel.yaml

title: Tour Carousel
dialog: travel:components/tourCarousel

references:
  tours:
    propertyName: tours
    referenceResolver:
      $type: JcrReferenceResolver
      targetWorkspace: tours

# Handle subproperties of tours:

   tourTypes:
    propertyName: tourTypes
    referenceResolver:
      $type: JcrReferenceResolver
      targetWorkspace: categories
 
   image:
    propertyName: image
    referenceResolver:
      $type: AssetReferenceResolver
      includeAssetMetadata: false



As an optional GraphQL fragment?

GraphQL was designed to handle this kind of querying/referencing.

What if you could provide an optional GraphQL fragment next to the template definition file. If it was present, then the component would only output this content.

/components/tourCarousel.graphql

{
    tours: Tours{ # Need a hint to know its type
        name
        duration
        image: Asset{
            link
            renditions(renditionNames: "1600") {
                renditionName
                link
            }
        }
        tourTypes: Category{ # Need a hint to know its type
            displayName
            icon{
                link
            }
        }
    }
}


As an optional JSON fragment?

Very similar to graphql fragment above.

If developer supplies a JSON file - it overrides the default response. Maybe use actual javascript??


/components/tourCarousel.json (JUST A SKETCH!)

{
    "tours": [
        {
            "name": `${name}`,
            "duration": `${duration}`,
            "image": {
                "link": `${image.link}`,
                "rendition": `${image.rendition["1600"]}`,
            },
            "tourTypes": [
                {
                    "displayName": `${displayName}`,
                    "icon": `${icon.link}`
                }
            ]
        }
    ]
}




  • No labels