RESTful API Support – Plain JAX-RS Services

1. Overview

Bloomreach Content (HST-2) supports integration with plain JAX-RS components. You can develop standard JAX-RS components for custom RESTful APIs and leverage HST-2 content retrieval and management features within those components.

Note: Bloomreach provides multiple options for exposing REST APIs. Review this overview to determine which approach fits your requirements.

To use plain JAX-RS services, configure the relevant mount(s) in the repository to use the JaxrsPlainRestPipeline. You must also enable this pipeline in your Spring configuration overrides.

Starting with brXM 12.1, you can automatically generate API documentation (/swagger.yaml or /swagger.json) in Swagger format. This enables integration with Swagger UI for interactive API exploration and testing.

2. Enabling a Plain RESTful Mount

To expose a plain JAX-RS services endpoint, configure a dedicated mount.

For example, the following configuration defines a restservices mount:

/restservices: jcr:primaryType: hst:mount hst:alias: restservices hst:ismapped: false hst:namedpipeline: JaxrsRestPlainPipeline hst:types: [rest]

This configuration creates a /restservices mount that enables a plain JAX-RS RESTful services endpoint. The JaxrsRestPlainPipeline processes requests for this mount and is provided by default in the HST-2 container.

3. Developing and Configuring Plain JAX-RS Components

Plain JAX-RS components follow the standard JAX-RS specification. Implement your components according to standard JAX-RS practices.

Map your JAX-RS resource class to a path. The following example maps the resource to /products/:

package org.hippoecm.hst.demo.jaxrs.services; @Path("/products/") public class ProductPlainResource extends org.hippoecm.hst.jaxrs.services.AbstractResource { @GET @Path("/{productType}/") public List<ProductRepresentation> getProductResources( @Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse, @Context UriInfo uriInfo, @PathParam("productType") String productType) { // Implementation omitted return null; } }

The JaxrsRestPlainPipeline selects the JAX-RS service endpoint based on the configured mount path.

For example, a request to http://localhost:8080/site/restservices/products/bike/ is resolved to the restservices mount. The pipeline delegates the remaining path /products/bike/ to the JAX-RS engine, which matches the productType path parameter and invokes the getProductResources() method.

To register your JAX-RS resource component, add a bean definition to the sourceList property of the customRestPlainResourceProviders bean. Example:

<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-3.0.xsd"> <!-- Import pipeline configurations for JaxrsRestPlainPipeline and others --> <import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-jackson.xml" /> <import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-plain-pipeline.xml" /> <import resource="classpath:/org/hippoecm/hst/site/optional/jaxrs/SpringComponentManager-rest-content-pipeline.xml" /> <!-- Register custom JAX-RS REST Plain Resource Providers --> <bean id="customRestPlainResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean"> <property name="sourceList"> <list> <!-- Wrap your JAX-RS component with SingletonResourceProvider --> <bean class="org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider"> <constructor-arg> <bean class="org.hippoecm.hst.demo.jaxrs.services.ProductPlainResource" /> </constructor-arg> </bean> </list> </property> </bean> <!-- This bean is for Content/Context Aware JAX-RS Services, not used for Plain JAX-RS Services --> <bean id="customRestContentResourceProviders" class="org.springframework.beans.factory.config.ListFactoryBean"> <property name="sourceList"> <list> </list> </property> </bean> </beans>

You can register additional custom JAX-RS components as needed.

4. Example Implementation

The following example shows a more complete implementation of a JAX-RS component:

package org.hippoecm.hst.demo.jaxrs.services; @Path("/products/") public class ProductPlainResource extends org.hippoecm.hst.jaxrs.services.AbstractResource { @GET @Path("/{productType}/") public List<ProductRepresentation> getProductResources( @Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse, @Context UriInfo uriInfo, @PathParam("productType") String productType) { List<ProductRepresentation> products = new ArrayList<ProductRepresentation>(); try { HstRequestContext requestContext = RequestContextProvider.get(); HstQueryManager hstQueryManager = getHstQueryManager(requestContext.getSession(), requestContext); String mountContentPath = requestContext.getResolvedMount().getMount().getContentPath(); Node mountContentNode = requestContext.getSession().getRootNode() .getNode(PathUtils.normalizePath(mountContentPath)); HstQuery hstQuery = hstQueryManager.createQuery(mountContentNode, ProductBean.class); Filter filter = hstQuery.createFilter(); filter.addEqualTo("demosite:product", productType); hstQuery.setFilter(filter); hstQuery.addOrderByDescending("demosite:price"); hstQuery.setLimit(10); HstQueryResult result = hstQuery.execute(); HippoBeanIterator iterator = result.getHippoBeans(); while (iterator.hasNext()) { ProductBean productBean = (ProductBean) iterator.nextHippoBean(); if (productBean != null) { ProductRepresentation productRep = new ProductRepresentation().represent(productBean); productRep.addLink(getNodeLink(requestContext, productBean)); productRep.addLink(getSiteLink(requestContext, productBean)); products.add(productRep); } } } catch (Exception e) { throw new WebApplicationException(e); } return products; } }

You can invoke the resource service URL from a client-side HTML page or script. For example:

<p> Product : <a href='<hst:link path="/restservices/products/${document.product}/" />' target='_blank' title='Click the left link to see all products of the same product type in XML generated by a Plain JAX-RS Service.'> ${document.product}</a> </p>

When using plain JAX-RS services, you must know the expected URL structure for each resource. In the example above, the <hst:link/> tag is used with a predefined path.

5. Matrix Parameter Support

Plain JAX-RS services can use matrix parameters via the @MatrixParam annotation.

Limitation: The current JAX-RS runtime library (Apache CXF) used by HST-2 does not support matrix parameters across multiple path segments.

For example, to use two matrix parameters (p1 and p2) with the URL http://localhost:8080/site/restservices/a/b, use:

http://localhost:8080/site/restservices/a/b;p1=1;p2=2

If you distribute matrix parameters across segments (e.g., http://localhost:8080/site/restservices/a;p1=1/b;p2=2), Apache CXF will not match the JAX-RS service or operation for /a/b.

6. Generating API Documentation in Swagger/OpenAPI Format

Starting with brXM 12.1, you can automatically generate API documentation in OpenAPI format for your custom plain JAX-RS service components.

To enable this, add the following bean definition to a Spring bean assembly XML file in site/components/src/main/resources/META-INF/hst-assembly/overrides/ (for example, swagger-config.xml):

<?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.xsd"> <bean id="hstOpenApiBeanConfig" class="io.swagger.v3.oas.integration.SwaggerConfiguration"> <property name="resourcePackages" value="org.hippoecm.hst.demo.jaxrs.services" /> <property name="cacheTTL" value="0"/> <property name="openAPI"> <bean class="io.swagger.v3.oas.models.OpenAPI"> <property name="info"> <bean class="io.swagger.v3.oas.models.info.Info"> <property name="title" value="REST API Example" /> <property name="version" value="1.0" /> <property name="description" value="Description of REST Services" /> <property name="termsOfService" value="http://www.example.com/terms-of-services.html" /> <property name="license"> <bean class="io.swagger.v3.oas.models.info.License"> <property name="name" value="Apache License, Version 2.0" /> <property name="url" value="https://www.apache.org/licenses/LICENSE-2.0" /> </bean> </property> <property name="contact"> <bean class="io.swagger.v3.oas.models.info.Contact"> <property name="email" value="[email protected]" /> </bean> </property> </bean> </property> </bean> </property> </bean> </beans>

After rebuilding and restarting your project, access the auto-generated API documentation at /openapi.yaml or /openapi.json under the REST API mount path (for example, /restservices/openapi.yaml or /restservices/openapi.json).

If you have a Swagger UI web application installed and configured to consume this documentation, you can view and interact with your API.

To add and test a Swagger UI module (such as http://localhost:8080/api-docs/) locally, refer to the api-docs submodule and configuration examples in the TestSuite project.

7. Summary

  • HST-2 supports standard JAX-RS components for RESTful APIs.
  • You can use HST Content Beans to retrieve or manage JCR content within plain JAX-RS components.
  • With plain JAX-RS services, you must know the URL patterns for each resource.
  • API documentation (/openapi.yaml or /openapi.json) in Swagger format can be generated automatically. You can use Swagger UI to view and test the API.
Share Feedback
Page: /build/rest-services/jax-rs-services/restful-api-support---plain-jax-rs-services
Section: Build
Category *