29 Building Your First Coherence REST Application
The Coherence examples that ship with the distribution also include an end-to-end example of a REST application. See Coherence REST Examples in Installing Oracle Coherence.
This chapter includes the following sections:
Overview of the Basic Coherence REST Example
The example in this chapter uses an embedded HTTP server in order to deploy a standalone application that does not require an application server. Additional deployment options are available. See Deploying Coherence REST.
Coherence for Java must be installed to complete the steps in this chapter. In addition, the following user-defined variables are used in this example:
-
DEV_ROOT
- The path to root folder where user is performing all of the listed steps, or in other words all of the following folders are relative toDEV_ROOT
. -
COHERENCE_HOME
- This variable must be a full path to thecoherence
directory of your Coherence installation.
Prerequisites
To build this example, you will need to have the following installed.
Required Software
-
JDK 17 or 21
-
Maven 3.8.5+
-
Coherence 14.1.2.0.0 (for installation instructions, see Installing the Oracle WebLogic Server and Coherence Software.
Dependencies
Install the following Coherence dependencies into your local Maven repository. Use the following commands, based on your operating system.
mvn install:install-file -Dfile=%COHERENCE_HOME%\lib\coherence.jar -DpomFile=%COHERENCE_HOME%\plugins\maven\com\oracle\coherence\coherence\14.1.2\coherence.14.1.2.pom mvn install:install-file -Dfile=%COHERENCE_HOME%\lib\coherence-rest.jar -DpomFile=%COHERENCE_HOME%\plugins\maven\com\oracle\coherence\coherence-rest\14.1.2\coherence-rest.14.1.2.pom mvn install:install-file -Dfile=%COHERENCE_HOME%\lib\coherence-http-netty.jar -DpomFile=%COHERENCE_HOME%\plugins\maven\com\oracle\coherence\coherence-http-netty\14.1.2\coherence-http-netty.14.1.2.pom
mvn install:install-file -Dfile=$COHERENCE_HOME/lib/coherence.jar -DpomFile=$COHERENCE_HOME/plugins/maven/com/oracle/coherence/coherence/14.1.2/coherence.14.1.2.pom mvn install:install-file -Dfile=$COHERENCE_HOME/lib/coherence-rest.jar -DpomFile=$COHERENCE_HOME/plugins/maven/com/oracle/coherence/coherence-rest/14.1.2/coherence-rest.14.1.2.pom mvn install:install-file -Dfile=$COHERENCE_HOME/lib/coherence-http-netty.jar -DpomFile=$COHERENCE_HOME/plugins/maven/com/oracle/coherence/coherence-http-netty/14.1.2/coherence-http-netty.14.1.2.pom
Generate the Classpath
pom.xml
in DEV_ROOT
with the following
contents:<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>com.oracle.coherence.rest.example</artifactId> <groupId>rest</groupId> <version>1.0.0</version> <name>Coherence REST dependencies</name> <packaging>pom</packaging> <properties> <coherence.groupId>com.oracle.coherence</coherence.groupId> <coherence.version>14.1.2-0-0</coherence.version> </properties> <dependencies> <dependency> <groupId>${coherence.groupId}</groupId> <artifactId>coherence-rest</artifactId> <version>${coherence.version}</version> </dependency> <dependency> <groupId>${coherence.groupId}</groupId> <artifactId>coherence</artifactId> <version>${coherence.version}</version> </dependency> <dependency> <groupId>${coherence.groupId}</groupId> <artifactId>coherence-http-netty</artifactId> <version>${coherence.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.inject</groupId> <artifactId>jersey-hk2</artifactId> <version>2.41</version> </dependency> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.1</version> </dependency> </dependencies> </project>
cp.txt
:mvn -q dependency:build-classpath -Dmdep.outputFile=cp.txt
Step 1: Configure the Cluster Side
The cluster-side cache configuration deployment descriptor configures a
cache and proxy. For this example, the proxy is configured to accept client HTTP
requests on localhost
and port 8080
. A distributed
cache named dist-http-example
is defined and is used to store client
data in the cluster.
To configure the cluster side:
Step 2: Create a User Type
Create the Person
user type, which is stored in
the cache and used to demonstrate basic REST operations.
To create the Person object:
Step 3: Configure REST Services
To configure the REST services:
Step 4: Start the Cache Server Process
DefaultCacheServer
). The cache server's classpath
must be configured to find all the configuration files that were created in the previous
steps, as well as the Person.class
. The classpath must also contain the
required dependency libraries. See Dependencies for Coherence REST. For the
sake of brevity, all of the dependencies are placed in the
DEV_ROOT
\libs
folder and are not individually
listed.
The DEV_ROOT
folder should appear as follows:
\ \config \config\example-server-config.xml \config\coherence-rest-config.xml \example \example\Person.class \libs \libs\*
The following command line starts a cache server process and explicitly names the
cache configuration file created in Step 1 by using the
coherence.cacheconfig
system property. In addition, it uses the
classpath created in Prerequisites.
set DEV_ROOT=%cd% java -Dcoherence.wka=127.0.0.1 -cp %DEV_ROOT%\config;%DEV_ROOT%;"$(type cp.txt)" -Dcoherence.cacheconfig=%DEV_ROOT%\config\example-server-config.xml com.tangosol.net.Coherence
export DEV_ROOT=`pwd` java -Dcoherence.wka=127.0.0.1 -cp ${DEV_ROOT}/config:${DEV_ROOT}:`cat cp.txt` -Dcoherence.cacheconfig=${DEV_ROOT}/config/example-server-config.xml com.tangosol.net.Coherence
ProxyService{Name=ExtendHttpProxyService, State=(SERVICE_STARTED), Id=…, OldestMemberId=1, Serializer=java}
Step 5: Access REST Services From a Client
The following sections demonstrate the semantics for PUT
, GET
, and Post
operations that a client would use to access the dist-http-example
cache. An example Java client built using Jersey follows and requires the Jersey-client-2.12.jar
library. See Performing Grid Operations with REST.
See the following example operations using the curl command.
Put Operations
PUT http://localhost:8080/api/dist-http-example/1 Content-Type=application/json Request Body: {"name":"chris","age":30}
PUT http://localhost:8080/api/dist-http-example/2 Content-Type=application/json Request Body: {"name":"adam","age":26}
GET Operations
GET http://localhost:8080/api/dist-http-example/1.json GET http://localhost:8080/api/dist-http-example/1.xml GET http://localhost:8080/api/dist-http-example/entries?q=name is 'chris' GET http://localhost:8080/api/dist-http-example/1.json;p=name GET http://localhost:8080/api/dist-http-example/count() GET http://localhost:8080/api/dist-http-example/double-average(age)
Post Operation
POST http://localhost:8080/api/dist-http-example/increment(age,1)
Sample curl Commands
The following are the curl commands to run the previous REST requests.
curl -v -H 'Content-Type: application/json' -X PUT http://localhost:8080/api/dist-http-example/1 -d '{"name":"chris","age":30}' curl -v -H 'Content-Type: application/json' -X PUT http://localhost:8080/api/dist-http-example/2 -d '{"name":"adam","age":26}'
curl -X GET http://localhost:8080/api/dist-http-example/1.json curl -X GET http://localhost:8080/api/dist-http-example/1.xml curl -X GET http://localhost:8080/api/dist-http-example/entries?q=name%20is%20%27adam%27 curl -X GET "http://localhost:8080/api/dist-http-example/1.json;p=name" curl -X GET "http://localhost:8080/api/dist-http-example/count()" curl -X GET "http://localhost:8080/api/dist-http-example/double-average(age)"
POST Operations
curl -X POST "http://localhost:8080/api/dist-http-example/increment(age,1)"
Sample Jersey REST Client
Create a file in the example directory called RestExampe.java
and
add the following contents. Compile using the same method as used previously for
Person.java
and run using:
SET CLASSPATH=%CP%;%DEV_ROOT%\config;%DEV_ROOT% java example.RestExample
java -cp `cat cp.txt`:. example.RestExample
package example; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; public class RestExample { public static void PUT(String url, MediaType mediaType, String data) { process(url, "put", mediaType, data); } public static void GET(String url, MediaType mediaType) { process(url, "get", mediaType, null); } public static void POST(String url, MediaType mediaType, String data) { process(url, "post", mediaType, data); } public static void DELETE(String url, MediaType mediaType) { process(url, "delete", mediaType, null); } public static void process(String sUrl, String action, MediaType mediaType, String data) { Client client = ClientBuilder.newClient(); Response response = null; WebTarget webTarget = client.target(sUrl); String responseType = MediaType.APPLICATION_XML; if (mediaType == MediaType.APPLICATION_JSON_TYPE) { responseType = MediaType.APPLICATION_JSON; } if (action.equalsIgnoreCase("get")) { response = webTarget.request(responseType).get(); } else if (action.equalsIgnoreCase("post")) { Entity<String> person = Entity.entity(data, responseType); response = webTarget.request(responseType).post(person); } else if (action.equalsIgnoreCase("put")) { Entity<String> person = Entity.entity(data, responseType); response = webTarget.request(responseType).put(person); } else if (action.equalsIgnoreCase("delete")) { Entity<String> person = Entity.entity(data, responseType); response = webTarget.request(responseType).delete(); } System.out.println(response.readEntity(String.class)); } public static void main(String[] args) throws URISyntaxException, MalformedURLException, IOException { PUT("http://localhost:8080/api/dist-http-example/1", MediaType.APPLICATION_JSON_TYPE, "{\"name\":\"chris\",\"age\":32}"); PUT("http://localhost:8080/api/dist-http-example/2", MediaType.APPLICATION_JSON_TYPE, "{\"name\":\"\ufeff\u30b8\u30e7\u30f3A\",\"age\":66}"); PUT("http://localhost:8080/api/dist-http-example/3", MediaType.APPLICATION_JSON_TYPE, "{\"name\":\"adm\",\"age\":88}"); POST("http://localhost:8080/api/dist-http-example/increment(age,1)", MediaType.APPLICATION_XML_TYPE, null); GET("http://localhost:8080/api/dist-http-example/1", MediaType.APPLICATION_JSON_TYPE); GET("http://localhost:8080/api/dist-http-example/1", MediaType.APPLICATION_XML_TYPE); GET("http://localhost:8080/api/dist-http-example/count()", MediaType.APPLICATION_XML_TYPE); } }