In Hybris and web development in general now, one of the most important use-case is consuming APIs. In this post, I will discuss how to consume a REST API that returns a JSON. This post is regarding how to use RestTemplate to consume. However, we should know that Hybris uses Jersey to consume REST APIs OOTB. To view details about using Jersey to consume in Hybris, visit the Wiki here.

I will be consuming using a GET request. Even though, I am implementing this in Hybris, it can be implemented in any Spring based application.

API information

In this API, we are getting the order status from a defined API.

Endpoint: https://foobar.com/api/order/{orderNumber}/detail
Response:

Response«OrderInformation» {
  body (OrderInformation, optional)
}
OrderInformation {
  orderNumber (string, optional),
  status (string, optional),
}

Now that the API information is defined, we can get to implementing and consuming this service.

Define the service that uses RestTemplate

In the <extension>-spring.xml, define the following bean and alias:

<alias name="defaultOrderStatusService" alias="orderStatusService" />
<bean id="defaultOrderStatusService" class="com.mySite.myExtension.orderstatus.foobar.service.impl.FooOrderStatusServiceImpl">
    <property name="url" value="#{configurationService.configuration.getProperty('webservice.foo.order.status.endPoint')}" />
    <property name="client">
        <bean class="org.springframework.web.client.RestTemplate">
            <constructor-arg>
                <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
                    <property name="readTimeout" value="#{configurationService.configuration.getProperty('webservice.foo.order.status.readTimeout')}" />
                    <property name="connectTimeout" value="#{configurationService.configuration.getProperty('webservice.foo.order.status.connectionTimeout')}" />
                </bean>
            </constructor-arg>
            <property name="messageConverters">
                <list>
                    <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter" />
                </list>
            </property>
        </bean>
    </property>
</bean>

Now let’s create the java class that this bean refers to.

Create defined Java class

Create the following java class in the specified location.

package com.mySite.myExtension.orderstatus.foobar.service.impl;

import com.mySite.myExtension.orderstatus.foobar.service.FooOrderStatusResponse;
import de.hybris.platform.servicelayer.config.ConfigurationService;
import org.apache.log4j.Logger;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.net.URI;
import java.text.MessageFormat;

public class FooOrderStatusServiceImpl {

	private static final Logger LOG = Logger.getLogger(FooOrderStatusServiceImpl.class);
	
	private ConfigurationService configurationService;
	private String url;
	private RestTemplate client;

	public ResponseEntity<FooOrderStatusResponse> fooOrderStatus(String orderId) {


		ResponseEntity<FooOrderStatusResponse> response = null;
		url = MessageFormat.format(url, orderId);


		try {
			URI uri = new URI(url);
			response = client.getForEntity(uri, FooOrderStatusResponse.class);

		} catch (Exception e) {
			LOG.error("Error getting order status from Foo at endpoint: " + url, e);
		}

		return response;
	}

	public ConfigurationService getConfigurationService() {
		return configurationService;
	}

	public void setConfigurationService(ConfigurationService configurationService) {
		this.configurationService = configurationService;
	}
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public RestTemplate getClient() {
		return client;
	}

	public void setClient(RestTemplate client) {
		this.client = client;
	}

}

We need to create the Response class.

FooOrderStatusResponse class

package com.mySite.myExtension.orderstatus.foobar.service;

import com.fasterxml.jackson.annotation.JsonProperty;

public class FooOrderStatusResponse {

    public FooOrderStatusResponse() {}

    @JsonProperty
    private OrderInformation body;

    public OrderInformation getBody() {
        return body;
    }

    public void setBody(OrderInformation body) {
        this.body = body;
    }
}

Now we need to define the OrderInformation object that we are using the body for:

OrderInformation

package com.mySite.myExtension.orderstatus.foobar.service;

public class OrderInformation {

    private String orderNumber;
    private String status

    public Integer getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(Integer orderNumber) {
        this.orderNumber = orderNumber;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
    
}

Add the properties

Since we are fetching the endpoint and the timeouts from the endpoint, we need to add those to our properties file:

webservice.foo.order.status.endPoint = https://foobar.com/api/order/{0}/detail
webservice.foo.order.status.readTimeout=3000
webservice.foo.order.status.connectionTimeout=3000

Calling out service class to consume the API

Now all we need to do is inject our service in the class we want to consume the API from and call the service method to consume.

    @Resource(name = "orderStatusService")
    private FooOrderStatusServiceImpl orderStatusService;

To consume the API, call the following method:

ResponseEntity<FooOrderStatusResponse> orderStatusResponseResponseEntity = orderStatusService.fooOrderStatus(orderId)

Now we should have a response from the endpoint. If there are any comments, please let me know. Visit all of my Hybris posts here.


1 Comment

John · August 31, 2020 at 2:15 pm

Can you give an example of the JSON that the hypothetical endpoint might return? Everything is working for me but I think I am misunderstanding the schema you provided.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *