Resource Prototypes
Resource prototypes are generated Java classes which implement the resources defined in the API definition. They perform particular operations by instantiating and routing logic for CRUD (Create Read Update Delete) and other API operations, such as, submit
, info
, and linkto
.
Resource prototypes are generated from the API definition XML as an interface. The interface is also generated with associated interfaces for the CRUD and API operations the resource can perform. To implement a resource prototype, you must create a class which implements the prototype interface itself as well as one of the operation interfaces; all other wiring is handled for the developer.
Implementing a single interface per prototype reduces the number of unneeded or out of scope data injections, as well as reducing the amount of code necessary in each resource prototype.
For example, to generate a ProfileResource
interface, a developer could define the following in profiles.xml
:
<resource>
<name>profile</name>
<description><![CDATA[The profile for the customer.]]></description>
<uri>{base.family}/{base.scope}/{profile-id}</uri>
<entity>profile</entity>
</resource>
This resource definition will generate a ProfileResource
interface class. Generated interfaces include specific operation interfaces for the resource, such as create and read. These interfaces are extended by the prototype.
Resource prototypes function without ever communicating directly with the Commerce Engine. The prototype layer communicates directly with the repository layer, and the repositories communicate with Commerce Engine. This allows for abstraction and isolation of a resource’s functionality from Commerce Engine functionality.
For more information see the Cortex Architecture and Call Stack documentation.
Implementing Operation Prototypes
Responsibilities
The created resource prototype class needs a constructor and an operation method. In general, you want to create one Prototype class per operation needed.
For example, to read for a profile entity, a developer might implement ReadProfilePrototype
, which implements ProfileResource.Read
. To update a profile entity, developers would add a class called UpdateProfilePrototype
, which implements ProfileResource.Update
.
The Constructor
The constructor initializes service dependencies and injects data. The constructor should be annotated with @Inject
. The parameters to the constructor should be annotated with appropriate qualifier annotations, e.g. @RequestIdentifier
or @ResourceRepository
, to specify assignment of injected data. See Data Injectors for more details.
For example, the constructor for a prototype designed to read a Profile
entity might look like:
@Inject
public ReadProfilePrototype(@RequestIdentifier final ProfileIdentifier profileIdentifier,
@ResourceRepository final Repository<ProfileEntity, ProfileIdentifier> repository) {
this.profileIdentifier = profileIdentifier;
this.repository = repository;
}
The Operation Method
The operation method of the prototype should correlate with the Prototype’s specific responsibility (i.e. onRead
, onUpdate
, onLinkTo
etc.). This method will be similar across an entity’s individual operation prototypes, with differences corresponding to the operations.
The operation method simply delegates to the relevant operation on the injected repository.
@Override
public Single<ProfileEntity> onRead() {
return repository.findOne(profileIdentifier);
}
Marking Your Bundle as a Prototype Bundle
To mark your bundle as a bundle that provides a Helix prototype, add the following snippet to your pom.xml
.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<obrRepository>NONE</obrRepository>
<instructions>
<Require-Capability>osgi.service; filter:="(objectClass=com.elasticpath.rest.helix.client.extender.BootstrapExtender)"; effective:=active,</Require-Capability>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.elasticpath.rest.helix</groupId>
<artifactId>helix-maven-plugin</artifactId>
</plugin>
The <Require-Capability/>
element under the maven-bundle-plugin
section, marks the prototype bundle as discoverable by the Helix runtime.
Enabling Validation
The helix-maven-plugin
enables compile-time validation of the prototype. If there are validation errors, the plugin will fail the build. The error output of the build indicates which validation rules are broken and gives hints on how to fix these errors. An example output of an validation error is:
[ERROR] Read operation for the resource BookingsPrototype does not have correct return type. It should be Observable<interface com.elasticpath.rest.definition.bookings.BookingIdentifier>
In this case, the read operation defined in the BookingsPrototype
resource class is returning the wrong return type. The return type should be of type Observable<interface com.elasticpath.rest.definition.bookings.BookingIdentifier>
.