Announcement: You can find the guides for Commerce 7.5 and later on the new Elastic Path Documentation site. The Developer Center continues to support Commerce 6.13.0 through 7.4.1.Visit new site

A Closer Look at the Extended Profiles Resource

A Closer Look at the Extended Profiles Resource

In this section, we take a closer look at how to add linking and reading strategies to a resource extension. By adding a link strategy, you can insert links pointing to your resource in other resources, which client developers can use to navigate to your resource.

By adding a read strategy, your resource can extract data from another resource's representation. This is how you can extend the functionality of an existing resource. You don't modify the existing resource's code; you add your customizations to a new resource and use a read strategy to get data from the existing resource's representation.

Pulling Profile Information into ExtensionProfile

The ExtensionProfile resource echoes both the user's profileId and user name from the representation returned by the profiles resource. To do this, the ExtensionProfile resource implements a read strategy. A read strategy is required to read the output from other resources.

The ExtensionProfile read strategy's execute method, shown below, extracts information from a profiles representation and sets information into ExtensionProfile's representation:

               <html><body>
<pre class="j-path">rest-resource-extensionprofile<span class="j-pathsep">/</span>src<span class="j-pathsep">/</span>main<span class="j-pathsep">/</span>java<span class="j-pathsep">/</span>com<span class="j-pathsep">/</span>extension<span class="j-pathsep">/</span>rest<span class="j-pathsep">/</span>resources<span class="j-pathsep">/</span>extensionprofile<span class="j-pathsep">/</span>command<span class="j-pathsep">/</span>impl<span class="j-pathsep">/</span>ReadProfileStrategy.java</pre>
<pre class="java"><span class="j-bkg">  </span>@Override
  <span class="j-key">public </span>ExecutionResult&lt;Representation&gt; execute<span class="j-sym">(</span><span class="j-key">final </span>Representation profile<span class="j-sym">) {

    </span><span class="j-blk">/*Profile representation returned from the kernel.*/
    </span>ProfileRepresentation profileRepresentation = ResourceTypeFactory.adaptRepresentation<span class="j-sym">(</span>profile, ProfileRepresentation.<span class="j-key">class</span><span class="j-sym">)</span>;

    Self profileSelf = profileRepresentation.getSelf<span class="j-sym">()</span>;
    String uri = URIUtil.format<span class="j-sym">(</span>resourceServerName, profileSelf.getUri<span class="j-sym">())</span>;
    Self self = SelfFactory.createSelf<span class="j-sym">(</span>uri, ExtensionProfileRepresentation.TYPE, <span class="j-num">0</span><span class="j-sym">)</span>;

    ExtensionProfileMutator extensionProfileMutator = ExtensionProfileMutator.create<span class="j-sym">()</span>;
    extensionProfileMutator.setProfileId<span class="j-sym">(</span>profileRepresentation.getProfileId<span class="j-sym">())
      </span>.setFamilyName<span class="j-sym">(</span>profileRepresentation.getLastName<span class="j-sym">())
      </span>.setName<span class="j-sym">(</span>profileRepresentation.getFirstName<span class="j-sym">())
      </span>.setSelf<span class="j-sym">(</span>self<span class="j-sym">)</span>;

    ResourceLink linkToProfile = ResourceLinkFactory.createFromSelf<span class="j-sym">(</span>profileSelf, ExtensionProfileResourceRels.PROFILE_REL,
      ExtensionProfileResourceRels.EXTENSION_PROFILE_REL<span class="j-sym">)</span>;
    extensionProfileMutator.addLink<span class="j-sym">(</span>linkToProfile<span class="j-sym">)</span>;

    Representation extProfileRepresentation = extensionProfileMutator.getRepresentation<span class="j-sym">()</span>;
    <span class="j-key">return </span>ExecutionResultFactory.createReadOK<span class="j-sym">(</span>extProfileRepresentation<span class="j-sym">)</span>;
  <span class="j-sym">}</span></pre>
</body></html>
            

Like the link strategy, the read strategy is injected into the resource operator. This time, a readExtensionProfileCommandBuilder is responsible for injecting the read strategy.

               <html><body>
<pre class="j-path">rest-resource-extensionprofile<span class="j-pathsep">/</span>src<span class="j-pathsep">/</span>main<span class="j-pathsep">/</span>java<span class="j-pathsep">/</span>com<span class="j-pathsep">/</span>extension<span class="j-pathsep">/</span>rest<span class="j-pathsep">/</span>resources<span class="j-pathsep">/</span>extensionprofile<span class="j-pathsep">/</span>impl<span class="j-pathsep">/</span>ExtensionProfileResourceOperatorImpl.java</pre>
<pre class="java"><span class="j-jdoc">/**
 * Processes the resource operations on ExtensionProfile.
 */
</span>@Singleton
@Named<span class="j-sym">(</span><span class="j-str">&#34;extensionProfileResourceOperator&#34;</span><span class="j-sym">)
</span>@Path<span class="j-sym">(</span>ResourceName.PATH_PART<span class="j-sym">)
</span><span class="j-key">public class </span>ExtensionProfileResourceOperatorImpl <span class="j-key">extends </span>LinkStrategyAwareResourceOperator <span class="j-sym">{

  </span><span class="j-key">private final </span>Provider&lt;ReadFromOtherCommandWithStrategies.Builder&gt; readCommandBuilderProvider;


  <span class="j-jdoc">/**
   * Constructor. Injecting via constructor is easier to test and more performant.
   *
   * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">linkCommandBuilder Link Command Builder.
   * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">readCommandBuilderProvider read command builder provider.
   */
  </span>@Inject
  ExtensionProfileResourceOperatorImpl<span class="j-sym">(
      </span>@Named<span class="j-sym">(</span><span class="j-str">&#34;linkToExtensionProfileCommandBuilder&#34;</span><span class="j-sym">)
      </span><span class="j-key">final </span>LinkCommandWithStrategiesBuilderProvider linkCommandBuilder,
      @Named<span class="j-sym">(</span><span class="j-str">&#34;readExtensionProfileCommandBuilder&#34;</span><span class="j-sym">)
      </span><span class="j-key">final </span>Provider&lt;ReadFromOtherCommandWithStrategies.Builder&gt; readCommandBuilderProvider<span class="j-sym">) {

    </span><span class="j-key">super</span><span class="j-sym">(</span>linkCommandBuilder<span class="j-sym">)</span>;
    <span class="j-key">this</span>.readCommandBuilderProvider = readCommandBuilderProvider;
  <span class="j-sym">}</span></pre>
</body></html>
            

Unlike the linkToExtensionProfileCommandBuilder, the readExtensionProfileCommandBuilder isn't a bean. This is because command builder classes, which are responsible for passing in input to the command, are different for each resource's CRUD commands. With link strategies, the same input (the list of link strategies a resource has) is passed into the link command, so they all use the same LinkCommandWithStrategiesBuilderProvider class.

The ExtensionProfile's command builder readExtensionProfileCommandBuilder is shown below. It's injected with the readExtensionProfileStrategies bean and passes a list of read strategies into the read command.

               <html><body>
<pre class="j-path">rest-resource-extensionprofile<span class="j-pathsep">/</span>src<span class="j-pathsep">/</span>main<span class="j-pathsep">/</span>java<span class="j-pathsep">/</span>com<span class="j-pathsep">/</span>extension<span class="j-pathsep">/</span>rest<span class="j-pathsep">/</span>resources<span class="j-pathsep">/</span>extensionprofile<span class="j-pathsep">/</span>command<span class="j-pathsep">/</span>impl<span class="j-pathsep">/</span>ReadExtensionProfileCommandBuilder.java</pre>
<pre class="java"><span class="j-jdoc">/**
 * Constructor.
 *
 * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">rfoBuilder ReadFromOtherCommandWithStrategies builder.
 * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">strategies Strategies map.
 */
</span>@SuppressWarnings<span class="j-sym">(</span><span class="j-str">&#34;PMD.LooseCoupling&#34;</span><span class="j-sym">)
</span>@Inject
ReadExtensionProfileCommandBuilder<span class="j-sym">(
    </span>@Named<span class="j-sym">(</span><span class="j-str">&#34;readFromOtherCommandWithStrategiesBuilder&#34;</span><span class="j-sym">)
    </span><span class="j-key">final </span>ReadFromOtherCommandWithStrategies.Builder rfoBuilder,
    @Named<span class="j-sym">(</span><span class="j-str">&#34;readExtensionProfileStrategies&#34;</span><span class="j-sym">)
    </span><span class="j-key">final </span>HashMap&lt;String, ReadFromOtherCommandStrategy&gt; strategies<span class="j-sym">) {

  </span><span class="j-key">super</span><span class="j-sym">(</span>rfoBuilder, strategies<span class="j-sym">)</span>;
<span class="j-sym">}</span></pre>
</body></html>
            

The readExtensionProfileStrategies bean is defined in applicationContext-resource-server.xml. It takes a read strategy as a constructor argument as shown:

               <html><body>
<pre class="j-path">rest-resource-extensionprofile<span class="j-pathsep">/</span>src<span class="j-pathsep">/</span>main<span class="j-pathsep">/</span>resources<span class="j-pathsep">/</span>spring<span class="j-pathsep">/</span>applicationContext-extensionprofile-resource.xml</pre>
<pre class="j-text"><code>&lt;!-- Strategy used to read an extension profile representation --&gt;
&lt;bean name="readExtensionProfileStrategies" class="java.util.HashMap"&gt;
	&lt;constructor-arg&gt;
		&lt;map key-type="java.lang.String" value-type="com.elasticpath.rest.command.read.ReadFromOtherCommandStrategy"&gt;
			&lt;entry key="application/vnd.elasticpath.profile" value-ref="readProfileStrategy"/&gt;
		&lt;/map&gt;
	&lt;/constructor-arg&gt;
&lt;/bean&gt;</code></pre>
</body></html>
            

The read strategy executes when the resource operator's processRead() method is called:

               <html><body>
<pre class="j-path">rest-resource-extensionprofile<span class="j-pathsep">/</span>src<span class="j-pathsep">/</span>main<span class="j-pathsep">/</span>java<span class="j-pathsep">/</span>com<span class="j-pathsep">/</span>extension<span class="j-pathsep">/</span>rest<span class="j-pathsep">/</span>resources<span class="j-pathsep">/</span>extensionprofile<span class="j-pathsep">/</span>impl<span class="j-pathsep">/</span>ExtensionProfileResourceOperatorImpl.java</pre>
<pre class="java"><span class="j-bkg">  </span><span class="j-jdoc">/**
   * Handles a request to the extension profile resource.
   *
   * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">resourceName resource server name.
   * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">resourceUri the resource uri
   * </span><span class="j-jdoc-key">@param </span><span class="j-jdoc">operation The Resource Operation
   * </span><span class="j-jdoc-key">@return </span><span class="j-jdoc">the operation result
   */
  </span>@Path<span class="j-sym">(</span>ResourceUri.PATH_PART<span class="j-sym">)
  </span>@OperationType<span class="j-sym">(</span>Operation.READ<span class="j-sym">)
  </span><span class="j-key">public </span>OperationResult processRead<span class="j-sym">(
      </span>@ResourceName
      <span class="j-key">final </span>String resourceName,
      @ResourceUri
      <span class="j-key">final </span>String resourceUri,
      <span class="j-key">final </span>ResourceOperation operation<span class="j-sym">) {

    </span>Command&lt;Representation&gt; cmd = readCommandBuilderProvider.get<span class="j-sym">()
      </span>.setResourceUri<span class="j-sym">(</span>URIUtil.normalize<span class="j-sym">(</span>resourceUri<span class="j-sym">))
      </span>.setRedirectPrefix<span class="j-sym">(</span>resourceName<span class="j-sym">)
      </span>.build<span class="j-sym">()</span>;

    ExecutionResult&lt;Representation&gt; result = cmd.execute<span class="j-sym">()</span>;

    <span class="j-key">return </span>OperationResultFactory.create<span class="j-sym">(</span>result, operation<span class="j-sym">)</span>;
  <span class="j-sym">}</span></pre>
</body></html>