Enhancing Resource to Read From Other (RFO)
Enhancing Resource to Read From Other (RFO)
This tutorial assumes you have created the terms and conditions resource in the Writing Your First Resource section and linked to it from the orders resource in Adding Links to Your Resource.
Read From Other (RFO) is a powerful Cortex capability that enables your custom resource to read data from another resource. Using RFOs, you can re-use another resource's functionality, instead of building that functionality from scratch. The totals resource is a good example of an RFO. totals uses an RFO to read a cart's lineitems, so it can process those lineitems and surface up the total cost of the items in the cart.
This tutorial enhances the terms and conditions resource you built in Writing Your First Resource to retrieve orders entity information using an RFO. After completing this tutorial, you can follow a link on the orders resource and see the terms and conditions resource, which will display the Order ID that was read from the orders resource.
Retrieving Order Information from Terms
We will add an RFO to the terms-and-conditions resource to read the Order ID from the orders resource. When you retrieve the terms and conditions resource, the Order ID will display in the message field.
{ "self": { "type": "elasticpath.orders.order", "uri": "/commerce-legacy/orders/{scope}/{order-id}", "href": "http://localhost:9080/cortex/orders/{scope}/{order-id}" }, "links": [ ... { "rel":"terms", "type":"{vendor}.terms.terms-and-conditions", "uri":"/commerce-legacy/terms/orders/{scope}/{order-id}", "href":"http://localhost:9080/cortex/terms/orders/{scope}/{order-id}" }, ... ] }terms and conditions resource with Order ID in the message field:
{ self: { type: "{vendor}.terms.terms-and-conditions", uri: "/commerce-legacy/terms/orders/{scope}/{order-id}", href: "http://localhost:9080/cortex/terms/orders/{scope}/{order-id}", }, message: "An example terms and conditions string for order {order-id}", links: [ ] }
Adding RFO to the Terms and Conditions Resource
To implement the Read From Other (RFO) pattern, we need to enhance OrderToTermsLinkHandler and add a new method to TermsResourceOperatorImpl. The orginal processRead() method remains unchanged to support reading terms directly using a /terms/id= URI.
- Update the OrderToTermsLinkHandler.java class:
- In the call to URIUtil.format, replace the hard-coded "id=" argument with resourceState.getSelf().getUri().
- Edit the TermsResourceOperatorImpl.java class and copy the following
processReadFromOrder() method to the bottom of the class. Take a
moment to review the differences between this method and the previously created
processRead() method.
/** * Handles read from order operation. * * @param orderEntity the order entity. * @param operation the resource operation. * @return the result */ @Path({AnyResourceUri.PATH_PART}) @OperationType(Operation.READ) public OperationResult processReadFromOrder( @AnyResourceUri final ResourceState<OrderEntity> orderEntity, final ResourceOperation operation) { TermsAndConditionsEntity entity = TermsAndConditionsEntity.Builder .builder() .withMessage("An example terms and conditions string for order " + orderEntity.getEntity().getOrderId()) .build(); ResourceState<TermsAndConditionsEntity> state = ResourceState .<TermsAndConditionsEntity>builder() .withEntity(entity) .withSelf(createSelf(operation.getUri())) .build(); return createReadOK(state, operation); }
- Add a new test to TermsResourceOperatorImplTest.java:
- Add these variables to the test
class:
private static final String ORDER_ID = "orderId"; private final OrderEntity orderEntity = OrderEntity.builder() .withOrderId(ORDER_ID) .build(); private final ResourceState<OrderEntity> orderState = ResourceState .<OrderEntity>builder() .withEntity(orderEntity) .build();
- And add this test
method:
@Test public void shouldBuildStateWithOrderValue() { // This string should match what was set for the message in TermsResourceOperatorImpl.processReadFromOrder() String entityValue = "An example terms and conditions string for order orderId"; OperationResult result = resourceOperator.processReadFromOrder(orderState, resourceOperation); ResourceState<TermsAndConditionsEntity> state = (ResourceState<TermsAndConditionsEntity>) result.getResourceState(); assertEquals(entityValue, state.getEntity().getMessage()); }
- Add any missing
imports.
In TermsResourceOperatorImpl.java, add the following imports: import com.elasticpath.rest.definition.orders.OrderEntity; import com.elasticpath.rest.resource.dispatch.operator.annotation.AnyResourceUri; In TermsResourceOperatorImplTest.java, add the following import: import com.elasticpath.rest.definition.orders.OrderEntity;
- Add these variables to the test
class:
- Run the following command to build the terms and conditions resource JAR
file:
mvn clean install
Testing the Terms RFO Link
At this point, you've added all the necessary logic to read an order from the terms and conditions resource and the final result can be verified.
- Open a command line and navigate to the directory containing your Cortex web application.
- Run the following command to build and run the Cortex web
application:
mvn clean tomcat7:run-war
Open Cortex Studio in a browser at http://localhost:9080/studio/:
- Submit a GET Request for /carts/{scope}/default.
- Follow the order link.
- Ensure that there is a link to terms on your order and the URI has the format /terms/orders/{scope}/{order-id}.
- Follow the terms link and ensure the terms and conditions are successfully displayed with the message containing an Order ID.
Congratulations, you just implemented the Read From Other (RFO) pattern.