Customize the Content HAL API Add-on
How to Extend the Services?
The built-in Content HAL APIs will be sufficient in most practical use cases. However, Content HAL API provides some extension points for customizability.
Spring Assembly Overrides
Content HAL API Add-on services are assembled in Spring Beans assembly XML files in classpath*:META-INF/hst-assembly/addon/com/onehippo/cms7/addon/halapi/*.xml resources.
If you want to customize any built-in service beans and if you're knowledgeable enough to do that, then you may want to override the bean definitions defined in classpath*:META-INF/hst-assembly/overrides/addon/com/onehippo/cms7/addon/halapi/*.xml resources.
What if I want to decorate the returned HAL Resource JSON objects?
You can implement a custom JcrContentHalResourceProcessor in order to add any extra properties, metadata or embedded resources by yourself:
public MyCustomHalResourceProcessor implements JcrContentHalResourceProcessor { @Override public boolean isProcessable(Node contentNode) { // Suppose we want to add one more extra property called 'externalSource' only for myhippoproject:externallysourced document variant node type. return contentNode.isNodeType("myhippoproject:externallysourced"); } @Override public ContentHalResource process(ContentHalResource resource, Node contentNode) { // Suppose we want to add one more extra property called 'externalSource' like the following. // In advanced cases, you might want to enrich the resource by adding additional properties from external data sources, too. resource.setProperty("externalSource", JcrUtils.getStringProperty(contentNode, "myhippoproject:externalsource", ""); } }
To register your custom JcrContentHalResourceProcessor, add a custom addon Spring assembly XML under classpath:META-INF/hst-assembly/overrides/addon/com/onehippo/cms7/addon/halapi/ to define your custom JcrContentHalResourceProcessor list bean (The bean ID must be "customContentHalResourceProcessors").
For example, add site/src/main/resources/META-INF/hst-assembly/overrides/addon/com/onehippo/cms7/addon/halapi/custom-hal-processors.xml like the following:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean id="customContentHalResourceProcessors" class="org.springframework.beans.factory.config.ListFactoryBean"> <property name="sourceList"> <list> <bean class="com.example.hal.MyCustomHalResourceProcessor"> </bean> </list> </property> </bean> </beans>
What if I want to add a new plain JAX-RS service?
Add a Spring Bean assembly XML file under classpath:META-INF/hst-assembly/overrides/addon/com/onehippo/cms7/addon/halapi/. e.g. site/src/main/resources/META-INF/hst-assembly/overrides/addon/com/onehippo/cms7/addon/halapi/custom-extra-plain-jaxrs.xml.
And add your custom plain JAX-RS service beans (e.g. com.example.hal.jaxrs.service.MyExtraCustomJaxrsResource) into customHalRestApiResourceProviders ListFactoryBean like the following example. Note that the list bean ID must be customHalRestApiResourceProviders.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <!-- Default empty list of custom plain resource providers to be overriden. --> <bean id="customHalRestApiResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean"> <property name="sourceList"> <list> <bean class="org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider"> <constructor-arg> <bean class="com.example.hal.jaxrs.service.MyExtraCustomJaxrsResource"> </bean> </constructor-arg> </bean> </list> </property> </bean> </beans>
If the custom plain JAX-RS service bean is annotated with a different path in the class level, it will work for that specific path with your custom service bean. For example, you sometimes might want to add a custom plain JAX-RS service bean to create or update document by POST invocation.