JET RESTful Resource pattern input file and the Java class it generates
WebSphere Commerce provides a Java Emitter Template (JET) called the JET RESTful Resource pattern. The JET RESTful Resource pattern generates a Java class that retrieves feeds from Web services for a specific URL. To generate the Java class, you must create a pattern input file that contains data that the Java class requires to retrieve the feed. The Java class is called a JAX-RS resource.
Format of the pattern input file
Pattern input files provide the required information to the JET RESTful Resource pattern using the following format:
<rest componentName="component_name" packageNamePrefix="package_name_prefix">
<noun name="noun_name" pluralNounName="plural_noun_name"
defaultAccessProfile="default_access_profile" defaultExpression="default_get_xpath_expression>
<findBy expression="get_xpath_expression" name="findby_name"/>
</noun>
</rest>
The following describes the variables in the pattern input file:
Input file variable | Description |
---|---|
component_name | The name of the component that contains the
Web service from which you want to create a feed. If you are using
an existing WebSphere Commerce service, obtain the component name
by viewing the list in this topic: WebSphere Commerce Web services Examples of component names are:
If you are creating a feed from a custom WebSphere Commerce Web service, use the name of the component containing the custom Web service. |
package_name_prefix | The prefix of the package that will contain
the Java class output by this pattern.
|
noun_name | The name of the noun you want to get from the Web service for the Atom feed. To view nouns available for WebSphere Commerce components, see WebSphere Commerce Web services. |
plural_noun_name | The plural form of the noun you want to get from the Web service for the Atom feed. Use the identical plural_noun_name value you defined in the Atom feed URL in the previous procedure. The WebSphere Commerce convention is to use the plural form of a noun in a RESTful URL. |
default_access_profile | The name of the default storefront access profile
to use for the WebSphere Commerce service request. The access profile
defines the data to include in the response. Access profiles are
defined for each noun in WebSphere Commerce Web services. Typically, storefront
access profiles start with IBM_Store instead of IBM_Admin . |
default_get_xpath_expression | (Optional) The XPath expression for the GET
service that gets all instances of a noun, rather than returning a
specific instance of the noun by its identifier. Include this parameter
in your pattern input file only if you need the JAX-RS resource
to get all instances of a noun. For example, the Catalog noun has
a GET XPath expression that gets all the sales catalogs for the store.
In this case, the attribute in the pattern input file is:
If your RESTful URL does not include an identifier, the JAX-RS resource uses the default_get_xpath_expression. |
get_xpath_expression | The XPath expression for the GET service that
gets a noun using the internal or external identifier you specified
in the URL in the previous procedure. Example of an XPath expression that uses an internal identifier–Get Catalog service:
This XPath expression gets a catalog by its unique ID and returns the catalog matching the ID. Important: When including the XPath expression in the pattern input file, specify the following characters for the numeric UniqueID value, regardless of what is in the documented XPath expression:
The previous example XPath expression must look like this in the pattern input file:
Note: WebSphere
Commerce does not provide a RESTful Web service for the Catalog noun,
but you could create one using the procedures in this section. Example of an XPath expression that uses an external identifier–Get MarketingSpotData service:
This XPath expression gets e-Marketing Spot data by its external identifier (in this case, its name) and returns the data for display to a customer. Important: When including the XPath expression in the pattern input file, if the identifier value is a string, specify the following characters for the string value, regardless of what is in the documented XPath expression:
The previous example XPath expression must look like this in the pattern input file:
|
findby_name | The suffix of the method name that is called
when the URL contains an identifier. The pattern will create a method
using this suffix for the name. In the generated Java class, the full
method name will be findByfindby_name .
The findby_name should match the identifier specified
for the XPath expression for the Get service. For example, for the
Get Catalog XPath expression in the previous row, an appropriate findby_name is Id . |
Sample pattern input file
This example input file will generate the Java class required to get feed data from the Get Catalog service based on the unique ID of the catalog:
<rest componentName="Catalog" packageNamePrefix="com.ibm.commerce">
<noun name="Catalog" pluralNounName="catalogs" defaultAccessProfile="IBM_Store_Details" defaultExpression="/Catalog[@primary='false']">
<findBy expression="/Catalog[CatalogIdentifier[(UniqueID={0})]]" name="Id"/>
</noun>
</rest>
Location of the pattern output file
The pattern generates a JAX-RS resource Java class at the following path, based on the variables you entered in the pattern input file:
package_name_prefix.component_name.rest.resources.noun_name.java
For example:
com.ibm.commerce.Catalog.rest.resources.Catalog.java
The following describes key snippets from the Java class file generated using the previous pattern input file example:
Sample snippet 1: JAX-RS URI to resource mapping
This
snippet is near the top of the class file. The @Path
annotation
defines the URIs that this class handles. The annotation is generated
based on the noun name in the pattern input file. In this example,
the Catalog class, or resource, will handle all URIs
in the form */stores/storeId/catalogs
.
/**
* This class converts RESTful Catalog requests into WebSphere
* Commerce Catalog requests and returns data in either XML, JSON, or
* Atom feed format.
*/
@Path("stores/{storeId}/catalogs")
@Encoded
public class Catalog {
…
Sample snippet 2: JAX-RS URI to method mapping
This is the middle section of the class file. Its purpose is to:- Determine the requested response formats based on the
responseFormat
query parameters and the HTTP Accept header. - Call the
findByName
helper method to perform the WebSphere Commerce service request. - Return the response.
The @Path
annotation defines the URIs that
this method handles. This value is appended to the path defined for
the class and is generated based on the findby_name value
specified in the pattern input. In this example, this method handles
all URIs in the form */stores/storeId/catalogs/findby_name
.
/**
* This method performs a GetCatalog by id request.
*
* @param id the Catalog id.
* @param storeId the store Id.
* @param accessProfile the access profile of the Get request.
* @param responseFormat the response format (xml, json, or atom).
* @return The Catalog noun in the specified format.
* @throws WebApplicationException
* @throws IOException
* @throws CatalogException
*/
@GET
@Produces( { "application/atom+xml", "application/json", "application/xml" })
@Path("{id}")
public Response findById(
@PathParam("id") String id,
@PathParam("storeId") String storeId,
@QueryParam(value = "accessProfile") String accessProfile,
@QueryParam(value = "responseFormat") String responseFormat
) throws WebApplicationException, IOException, CatalogException {
final String METHODNAME = "findById(String, String, String, String, String, String)";
if (com.ibm.commerce.foundation.common.util.logging.LoggingHelper
.isEntryExitTraceEnabled(LOGGER)) {
LOGGER.entering(CLASSNAME, METHODNAME);
}
Response result = null;
Object[] params = { id };
String expression = MessageFormat.format(FIND_BY_ID_XPATH, params);
// Perform the service request and return the response in the appropriate format.
result = getCatalog(expression, accessProfile, responseFormat);
if (com.ibm.commerce.foundation.common.util.logging.LoggingHelper
.isEntryExitTraceEnabled(LOGGER)) {
LOGGER.exiting(CLASSNAME, METHODNAME);
}
return result;
}
Sample snippet 3: Find by name helper method
This snippet is near the bottom of the class file. Its purpose is to:- Create a GET service request for the noun using the GET XPath expression defined in the pattern input file.
- Use the JAX-RS runtime to convert the response into Atom format.
/**
* This method performs a <code>GetCatalog</code> service request.
*
* @param expression the XPath expression.
* @param accessProfile the access profile of the get expression.
* @param responseFormat the response format.
* @return the Catalog noun.
* @throws CatalogException the exception representing the error of the
* <code>GetCatalog<code> request.
* @throws WebApplicationException
* @throws IOException
*/
protected Response getCatalog(String expression, String accessProfile, String responseFormat)
throws CatalogException, WebApplicationException, IOException {
final String METHODNAME = "getCatalog(String, String, String)";
if (com.ibm.commerce.foundation.common.util.logging.LoggingHelper
.isEntryExitTraceEnabled(LOGGER)) {
LOGGER.entering(CLASSNAME, METHODNAME);
}
// Get the response format, either from the Http header or URL, the URL takes precedence.
MediaType format = StoreConfigurationHelper.getResponseFormat(responseFormat, headers);
if (accessProfile == null) {
accessProfile = DEFAULT_ACCESS_PROFILE;
}
// Build the Get request.
SelectionCriteriaHelper selectionCriteria = buildExpression(expression, accessProfile);
GetType getVerb = buildGetVerb(selectionCriteria.getSelectionCriteriaExpression());
// Perform the service request.
CatalogFacadeClient client = new CatalogFacadeClient(businessContext, null);
DataObject dataArea = (DataObject) client.getCatalog(getVerb);
// For XML or JSON, the JAX-RS runtime will resolve the appropriate provider.
// For Atom, the feed is directly populated.
Response result = null;
if (MediaType.APPLICATION_ATOM_XML_TYPE.isCompatible(format)) {
AtomFeedSDOProvider provider = new AtomFeedSDOProvider();
AtomFeed feed = provider.writeTo(dataArea, businessContext, uri, context);
result = Response.ok(feed).type(MediaType.APPLICATION_ATOM_XML).build();
} else {
result = Response.ok(dataArea).type(format).build();
}
if (com.ibm.commerce.foundation.common.util.logging.LoggingHelper
.isEntryExitTraceEnabled(LOGGER)) {
LOGGER.exiting(CLASSNAME, METHODNAME);
}
return result;
}