Elastic Path Commerce Development

Resource Identifiers

Resource Identifiers

A resource identifier is a class which represents the URI for a specific resource. Resource identifiers take the <uri-part/> element in a resource definition and convert them to Java types which are then used in prototype classes.

Resource identifier classes ensure type safety, and allow you to avoid constructing URIs manually. They provide Builder classes to build URIs accurately as needed, and @Inject annotations to inject those URIs into prototypes. These Builder classes also perform runtime validation, ensuring that all required components are present.

For certain API modeling patterns, Helix programming model resources also perform validation on identifier components to ensure that, for example, the caller has access to all referenced resources.

Simple Identifiers

Consider the following resource definition:

  <name>carts</name>
  <description>Family for carts</description>

  <uri-part>
    <name>cart-id</name>
    <description>The cart identifier.</description>
    <string/>
  </uri-part>

  <resource>
    <name>cart</name>
    <description>A cart resource. It can have line items, orders and totals.</description>
    <uri>/{base.family}/{base.scope}/{cart-id}</uri>
    <entity>cart</entity>
  </resource> 
      

The URI for the cart resource is /carts/{base.scope}/{car-id}. The corresponding resource identifier class is CartIdentifier.

CartIdentifier is actually an interface which extends ResourceIdentifier. The interface includes a getCartId() method:

  @Property(name = CART_ID)
  IdentifierPart<String> getCartId();
      

It also contains a generated Builder which is used to construct instances of the identifier:

  CartIdentifier myNewIdentifier = CartIdentifier.builder()
                                          .withCartId(StringIdentifier.of("some-id"))
                                          .build();
      

The URI-part can be injected into prototype instances using the @Inject annotation.

To @Inject the cart-id URI-part, use the following method signature:

  @Inject
  @UriPart(CartIdentifier.CART_ID)
  private IdentifierPart<String> cartId;
      

The entire resource identifier, including the the URI-part, can also be injected into prototype instances using the @Inject annotation in the method signature:

  @Inject
  @RequestIdentifier
  private CartIdentifier cartIdentifier;
      

Composite Identifiers

Resource identifiers can also be "composed" of other resource identifiers (which, in turn, may be "composed" of other resource identifiers).

Consider the following resource definition:

  <name>listcreate</name>
  <description>Family for list create</description>

  <uri-part>
    <name>line-item-id</name>
    <description>The line item identifier. </description>
    <string/>
  </uri-part>

  <resource>
    <name>line-items</name>
    <description>The line items list in a cart.</description>
    <uri>{cart}/lineitems</uri>
    <list-of>line-item</list-of>
  </resource>

  <resource>
    <name>line-item</name>
    <description>An individual line item in a cart.</description>
    <uri>{line-items}/{line-item-id}</uri>
    <entity>line-item</entity>
  </resource>
      

The URIs of both line-items and line-item resources are a composite identifier. The {cart} token contained within the URI of the line-items resource is itself the full identifier of the cart resource, and the {line-items} token contained within the URI of the line-item resource is the full identifier of the line-items resource.

Note: The code-generation tooling will validate your <uri/> elements to ensure that you are assembling your composite URIs correctly.

Examining the generated LineItemIdentifier interface, you'll find an accessor method for obtaining LineItemsIdentifier:

   @Property(name = LINE_ITEMS)
   LineItemsIdentifier getLineItems();
      

There's also an accessor method for obtaining IdentifierPart:

   @Property(name = LINE_ITEM_ID)
   IdentifierPart<String> getLineItemId();
      

Composite resource identifiers can be constructed using the generated Builder classes. Builder classes are obtained by calling the static builder() method on the generated Identifier, just as simple identifiers can be constructed:

  LineItemIdentifier lineItemIdentifier = LineItemIdentifier.builder()
    .withLineItems(LineItemsIdentifier.builder().build())
    .withLineItemId(StringIdentifier.of("some-id") .build();
      

Helix decomposes the resource URI into a composite identifier, and verifies that the caller has access to all of the referenced resources. In the case of line-items, it verifies that the caller has access to /{base.family}/{base.scope}/{cart-id}. If the caller does not have the necessary access, the operation is rejected.