Customize the Content HAL API Add-on - BloomReach Experience - Open Source CMS

This article covers a Hippo CMS version 12. There's an updated version available that covers our most recent release.

Customize the Content HAL API Add-on

BloomReach offers Enterprise support for this feature to BloomReach Experience customers. The release cycle of this feature may differ from our core product release cycle. 

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", "");
    }
}
#isProcessable(...) method shown in the above example has become available since v2.0.2. In the previous versions, you had to add that kind of conditions in #process(...) method.

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.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?