Build native Node.js applications with Coherence backend
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.
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
MapEvents, we’ll send a similar SSE event to the React front-end using the
@toverux/expresse SSE Express middleware.
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
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!
The complete Express application we’ve built is available here. The
README file contains all the details you’ll need to get started. Enjoy!