The Coherence JavaScript Client
By: Ryan Lubke
Tags: Nodejs, Introduction, Coherence, Expressjs, JavaScript

The Coherence JavaScript Client

In this article we’ll introduce you to the Coherence JavaScript Client, released at the end of August. For those of you unaware of the release, please see Randy’s introduction.

This article assumes you’ve read Aleks’ article describing the REST API implementation for a simple To Do List application. We’ll be using the same React front-end Aleks wrote to demonstrate that implementation but will re-implement the REST API itself as an Express application running on Node.js and will use the Coherence JavaScript Client to implement data access logic.

To start, let’s include the JavaScript client and other dependencies we’ll need to the package.json :

Now we can start building the Express backend the React UI will communicate with.

Firs, let’s import what we need:

Next, we’ll perform initial configuration for Express:

Nothing special here, aside from using Express instead of the WebPack development server to serve the compiled React application.

Next, we establish our session to the Coherence NamedMap containing the tasks:

That’s it! We’re now ready to begin developing the REST endpoints. Let’s refresh our memories of the endpoints defined in Aleks’ article:

Let’s go down this list and implement each of these one by one.

The GET /api/tasks/events endpoint is responsible for registering a listener with the todos map so that we can funnel the events to the client as a Server-Sent Event (SSE). This allows the application to update the UI based on mutations to the map.

This is pretty straightforward. As the MapListener receives MapEvents , we’ll send a similar SSE event to the React front-end using the @toverux/expresse SSE Express middleware.

The GET /api/tasks endpoint allows the application to obtain all or a subset of tasks.

A couple items are of note in this implementation. First is the use of the filter to allow the UI to query only completed or non-completed tasks. If the query parameter is omitted, then all tasks — regardless of their completion status — will be returned. The second is having to copy the contents of the RemoteSet returned by the Coherence JavaScript API into an array. This is due to Express’ limiting what can be sent over the wire to a Buffer , string , or array.

Next up is POST /api/tasks , which allows for the creation of new tasks:

Simple. Create a new task, insert it into the map, and return the result. The createTask helper function does bear some discussion:

Notice the use of '@class' = 'Task' — this is a key component for Java interoperability. Aleks’ article discusses this aspect in detail, but in short, when this payload is deserialized in Coherence, it will look for the Task Java class, instantiate it, and set the instance properties based on the JSON payload. If we did not do this, then Coherence would use a different class to represent the task (a basic JsonObject class), which would break the JAX-RS server implementation and JavaFX client. It’s also important to remember that the @class metadata must be the first property of any class that will be serialized for interoperability.

Now, we’ll need a way to delete tasks by ID. This will be done by the DELETE /api/tasks/:id endpoint:

Straightforward. Delete the task as designated by the path parameter. If the delete returns a value, return an HTTP status of 200; if not, return a status of 404.

Similarly, we’ll need a way to delete only completed tasks:

This implementation shows off the power of Coherence entry processors. Instead of getting all tasks locally and scanning them to remove completed tasks ourselves, we simply invoke a conditional remove processor that removes all completed tasks from within the cluster.

The final endpoint we need is PUT /api/tasks/:id which allows us to update a task’s description or completion status:

Again, we leverage the power of entry processors to update the appropriate entry in-place, without having to retrieve it, update it locally, and push it back into the map.

We can now wrap up the Express server implementation by listening to the configured port:

That’s it! Assuming the Coherence server from the original article is running locally, we can start the Express server and verify that we have a working application by visiting http://localhost:5000

Feel free to play with the application and create some tasks. If you want to make it more interesting, open the application in multiple browser windows and see how all of them are kept in sync via events as you make the changes.

You can also access the same front end via the existing Java server implementation on port 7001, or even using JavaFX client — all of them should remain in sync, regardless of which client is making changes to the data store.

Let’s create a task and complete it to ensure things are working as intended:

This task is done, and now, here at the end of the article, we can mark it complete!