Filtering allows you to determine the output that is displayed from a resource. This allows you to control the fields and links in the response from a resource, as well as enable clients to have similar controls from the request by creating filters. Filters also provide support for custom properties and data-type extensions.
You filter a resource by using the payload schema XML, which is described in detail in the Working with the Payload Schema section.
The validation schema can filter a resource by any of the following steps:
Using the
filterId
property of the@Endpoint
annotation, which is described in Associating a Filter with an EndpointSetting the
overrideFilterId
property on theRepresentationModel
, which is described in Override Filter ID Builder MethodSetting the
useFilterId
query parameter, which is described in Using Query Parameters
Using the Payload Schema XML
Definitions for filtering are contained within a single XML file located at /atg/dynamo/service/
. You can access the
validator/payloadschema.xmlPayloadSchemaRegistry
component using the Dynamo Server Admin. The following is an example of a payload schema for the default API order summary:
<schema id="orders-Default" use-schema-id="orders_Summary"/> <schema id="orders-Summary"> <bean class="java.util.List"/> <embedded name="items" expand="true" use-schema-id="orders.id-Summary"/> </schema >
The attributes and elements that you use to set up filtering are described in the Working with the Payload Schema section.
Associating a Filter with an Endpoint
The @Endpoint
annotation has a filterId
property that defines which filter to use during output. Endpoints that output data should have a filterId
defined or an exception will be thrown.
Note: Assigning a filter to an endpoint is not required, as there are additional methods that you can use to set a filter for an endpoint; however, it is best if you provide a filterId
for each endpoint so that there is always a default ID. If a filterId
is not defined, the framework attempts to retrieve the validator defined by the validatorId
on the endpoint and use it to filter the output.
The following is an example of an Orders
resource with a filter specified for the endpoint:
@Endpoint(id="test.orders.orderId", filterId="orders.id-Full") public RepresentationModel defaultGet(@PathParam("orderId") String pOrderId) { }
Working with Simple and Hidden Properties
You can activate the include-all-simple
attribute on the schema
element and the hidden
attribute on the property
or bean-property
elements. This makes the PayloadSchemaRegistry
attempt to create configuration and validators for all simple properties. By default, both the include-all-simple
and hidden
attributes are set to false
. Setting the include-all-simple
attribute to true
allows the inclusion of properties in the JSON output that are not hidden by the hidden
attribute, as well as simple properties that are not explicitly specified.
For additional information on the include-all-simple
property, refer to the Working with the Payload Schema section.
The following example shows a bean of class atg.TestOrder
that contains the id
, description
, state
and profileId
properties and the following filter:
<schema id="orders.id-Full" include-all-simple="true"> <bean class="atg.TestOrder"/> <property name="profileId" hidden="true"/> </schema>
Based on the example above, this JSON output would be produced:
{
"id": "o12345",
"state": "SUBMITTED",
"description": "This is a test Order",
...
< + resource metadata
>
}
By default the include-all-simple
attribute is set to false
, and only those properties that have been explicitly specified and not hidden will display.
The following example excerpt shows the atg.TestOrder
bean with the include-all-simple
attribute set to false
:
<schema id="orders.id-Full" include-all-simple="false"> <bean class="atg.commerce.order.Order"/> <property name="id" writeable="false"/> <property name="state" writeable="false"/> … </schema>
Based on this example, the following JSON would be produced. Note that only the id
and state
properties are displayed as they are explicitly not hidden:
{
"id": "o12345",
"state": "SUBMITTED",
...
< + resource metadata
>
}
Customizing Property Output
You can customize the output of properties by using the property-customizer
attribute of the property
element. This attribute specifies a Nucleus component that is a class implementing the atg.service.filter.bean.PropertyCustomizer
interface. For example:
<schema id="orders.id-Full" include-all-simple="true"> <bean class="atg.commerce.order.Order"/> <property name="orderTotal" property-customizer="atg.PricePropertyCustomizer"/> </schema>
The following example shows a PricePropertyCustomizer
:
public class PricePropertyCustomizer implements PropertyCustomizer { public Object getPropertyValue(Object pTargetObject, String pPropertyName, Map<String,String> pAttributes) throws BeanFilterException { Double value = (Double)DynamicBeans.getPropertyValue(pTargetObject, pPropertyName); return "£" + String.valueOf(value); } }
The above example would produce the following JSON:
{ "id": "o12345", "state": "SUBMITTED", "orderTotal": "£100.21", ... < + resource metadata > }
Filtering Embedded Resources
You can use the embedded
element of the payload schema XML for filtering embedded resources. By default, embedded resources and sub-resources occur in the response as a self
link. The following is an example of a HAL output for a resource with a product sub-resource:
{ ... <resource properties> ... _embedded":{ "product":{ "_links":{ "self":{ "href": "test/products/prod0001" } } } } }
Schemas can be configured to provide the whole representation of the embedded resource or sub-resource by using the hidden
attribute on the embedded
element. For example:
<schema id="orders.id-Full" include-all-simple="true"> <bean class="atg.TestOrder"/> <embedded name="commerceItems" hidden="false"/> </schema>
The above example would produce the following JSON:
{ "id": "o12345", "state": "SUBMITTED", ... "commerceItems": [ { "id": "ci1", "quantity": "3", "productId": "prod001" "_links":{ "self":{ "href": "test/orders/commerceitems/ci1" } } }, { "id": "ci2", "quantity": "2", "productId": "prod006" "_links":{ "self":{ "href": "test/orders/commerceitems/ci2" } } }, ], }
The embedded
element has a use-schema-id
attribute that you can use to override the schema defined by an endpoint when the embedded resource or sub-resource is provided as part of the root response. For example, the commerceItems
GET endpoint could be configured to use the commerceitem.id-Full
validator:
@Endpoint(id="test.orders.commerceitems", filterId="commerceitems.id-Full") public RepresentationModel defaultGet(@PathParam("itemId") String pItemId){
The payload schema XML can override this so that the commerceitem.id-Summary
validator is used when posting the order root resource:
<schema id="orders.id-Summary"> <bean class="java.util.List"/> <embedded name="items" expand="true" use-schema-id=" commercieitem.id-Summary"/> </schema>
For additional information on the embedded
and hidden
elements, refer to the Working with the Payload Schema section.
Working with the Collection Resource Payload Schema XML
If a collection resource does not have any state, then it should be set to the type of collection that will be returned. The members for a collection are embedded in the output in an items
array. The payload schema XML should include an embedded tag for items
if the members of the collection should be included in the response. A self
link for each member of the collection will be included unless the hidden="false"
attribute is explicitly set on the embedded tag. If the hidden="false"
attribute is set, the resource representation will be returned in the response. In this case, the use-schema-id
must be set so that the framework can filter each individual member of the collection:
<schema id="products-Summary"> <bean class="java.util.Collection"/> <embedded name="items" hidden="false" use-schema-id="products.id-Summary"/> </schema>
For additional information on collections, refer to the Using Embedded Resources section. For detailed information on filtering tags, refer to the Working with the Payload Schema section.
Setting the Filter Depth
As well as using the payload schema XML to filter individual properties of a bean, you can also filter the whole resource to a depth known as a filter depth. This allows you to control the nested level at which a filter is applied. Filter depth is useful when working with embedded resources that have a potential for circular reference.
The @Endpoint
annotation has an optional filterDepth
property that allows you to determine resource hierarchy depth. A filterDepth
of 0 indicates that all resource properties will be displayed, but bean properties will be filtered out. A filterDepth
of 1 indicates that all resource properties will be display, as well as bean properties, etc.
The filterDepth
of a root resource overrides the setting on any sub-resource output of a representation. If an order resource has a filterDepth
of 1 and it contains CommerceItem
sub-resources whose endpoint settings had a filterDepth
of 2, the filterDepth
of the order resource overrides that of the CommerceItems
.
Using Query Parameters
You can filter the response output using query parameters:
useFilterId
– TheuseFilterId
specifies a preconfigured schema when filtering a resource. For example:context
/v1/orders/getOrder/012345?useFilterId=orders.Id-Fullfields
– Thefields
query parameter specifies which fields or embedded relation names should be returned, separating each by commas. Only the specified fields are included in the response. Note that you can use dot (.
) notation and asterisk (*
) wildcards to include nested fields in a response. For example:context
/v1/orders/getOrder/012345?fields=id,description,st*links
– By default, all links for a resource are included in the response. Thelinks
query parameter specifies which links should be returned, with links separated by commas. For example:context
/v1/orders/getOrder/012345?links=self,submitOrderexpand
– By default, all embedded resources and sub-resources of a root resource output contain aself
link. Theexpand
query parameter returns the entire representation of the embedded resource or sub-resource. Resource names are separated by a comma. To get the entire representation of all embedded or sub-resources, use?expand=all
. The following example displays all resource forcommerceItems
andshippingGroups
:context
/v1/orders/getOrder/012345?expand=commerceItems,shippingGroupsexclude
– Opposite to the fields parameter, this is a comma separated list of field and/or embedded relation names that should be excluded from the response. Dot notation is supported, however wildcards are not.filterDepth
– Specifies a response depth that overrides the endpoint filter for this request. Refer to the Setting the Filter Depth section for additional information.
For information on additional query parameters, refer to Configuring Pagination for Collection Resources and Using Etags for Version Tracking.