Hello, Coherence — Bootiful Spring
The simplest way to build stateful and scalable Spring Boot apps
--
Last year, we published a series of articles on building a simple task management system using Oracle Coherence with Helidon MP, to showcase the Coherence integration with Eclipse MicroProfile. Since then we have added support for two additional popular Java application frameworks: Micronaut and Spring.
In fact, this article follows right on the heels of an article published by my colleague Ryan Lubke covering the Micronaut integration. Now it’s show time to add the Spring perspective of creating a Spring Boot-based To Do application using the open-source Oracle Coherence CE as the backend.
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
Let’s get started with Initializr
A great starting point for Spring Boot applications is Spring Initializr at https://start.spring.io/. It allows you to create fully functioning Spring Boot starter applications with only the dependencies you need.
For the To Do app, we will add the Spring Web dependency as we need to provide a REST API.
Generate the application and unzip it on your computer. At this point the application will start up but not do anything, yet. Nonetheless, this skeleton application is already doing a lot of heavy lifting for us.
When you look at the initial pom.xml
file, you will notice that it specifies the spring-boot-starter-parent
as the parent project. This provides default configurations for our project, as well as default Maven plugin configurations. It also inherits dependency management via spring-boot-dependencies
and thus manages dependency versions that work and are tested as part of the specified Spring Boot version, which in this case is 2.5.6
.
Besides the section that defines versions for dependencies not controlled by Spring Boot, we also use the spring-boot-maven-plugin
which allows you to package the executable JAR file and even to execute the application without building it first.
The main entry point into the To Do List application is the class com.oracle.coherence.examples.todo.server.
which is annotated with
TodoListSpringServerApplication@SpringBootApplication
. This Spring Boot-specific annotation will trigger component scanning and automatically discover defined REST controllers, services and Coherence repository classes.
Add Coherence Spring Dependencies
Before adding the business logic, we need to add three more dependencies:
- Coherence Spring Boot Starter
- Coherence Spring Data
- Coherence CE
By just adding these dependencies, the application will be auto-configured when the Spring Boot application starts and you will see an embedded Coherence instance being started as well.
Das Modell
Before we can interact with Coherence, we need to define the domain model, which for this application is super-simple. All we need is a Task
class comprised of just a few properties:
The instances of the Task
will be persisted to Coherence using our Spring Data repository support. As you can see, the Task
class is quite basic, just defining a few properties. In fact, the only requirement when persisting data via Coherence is that the class needs to be serializable using one of the supported serialization formats, and, when using Coherence Spring Data, we must define a primary key. For this we annotate the primary key property id
using the org.springframework.data.annotation.Id
annotation.
Tip: You may want to also check out the recently published article on the release of Coherence Spring 3.0.0 to learn more about the specifics of its features and how Coherence Spring can make your life as a Spring developer easier when using Oracle Coherence.
The Spring Data Repository
In order to interact with Coherence, we will take advantage of Coherence Spring Data and the pixie dust it provides. All we have to create is an interface SpringDataTaskRepository
, which extends CoherenceRepository
. The interface is also annotated with @CoherenceMap(“tasks”)
allowing us to customize the name of the Coherence NamedMap
we are going to use, which in this case is tasks
:
Spring Data Task Repository
This simple interface will provide all CRUD operations needed for the To Do application.
Give me Services
As good citizens we will add the SpringDataTaskService
which sits between the TaskRepository
and the (not-yet-created) REST controller. We certainly could have just used the TaskRepository
directly from within the REST controller, considering that this is such a simple example. However, the separation allows us to keep any complicated “business logic” out of the REST controller itself.
The TaskService
interface:
With the corresponding implementation SpringDataTaskService
:
SpringDataTaskService
The SpringDataTaskService
will use the SpringDataTaskRepository
to interact with Coherence. We will also add a simple TaskNotFoundException
class, which is thrown by the service in case where the requested Task
does not exist.
TaskNotFoundException
The REST Controller
And finally we expose the REST API. The application has a single RestController class called ToDoController
containing all relevant methods to retrieve, update and delete Tasks
. As you may notice, there is absolutely no reference to the underlying Coherence infrastructure whatsoever in this class. It is all tidily stowed away via the service layer.
We are almost done at this point but there is one more little thing we like to add.
Global Exception Handler
In case you try to retrieve a Task
that does not exist, we throw the TaskNotFoundException
. We should handle it as to not cause a pesky 500
error blowing up into the face of your users. Therefore, we add a ControllerAdvice
, which basically tells Spring to return a 404
status code instead, which is the much nicer thing to do.
We are finally done. But…
¡Look, no configuración!
That’s right, we now have a working Spring Boot application, powered by Coherence with absolutely ZERO configuration in application.properties
. How cool is that?
Boot me up, Scotty
The simplest way to run our To Do application is to use the aforementioned spring-boot-maven-plugin
:
mvn spring-boot:run
Of course, you can also build the project first and run the application as an executable jar:
mvn clean package
java -jar target/todo-list-spring-server-0.0.1-SNAPSHOT.jar
Or if you’re more of a Docker aficionado, Spring Boot has built-in Docker support (Docker daemon must be running):
mvn spring-boot:build-image
docker run -p 8080:8080 todo-list-spring-server:0.0.1-SNAPSHOT
Once executed, we can see the Spring Boot and the Oracle Coherence banners being printed and the REST endpoints will be exposed on port 8080
.
The REST API
We can execute the REST calls to see if everything works as expected. Using thecurl
tool, we will execute a series of commands. As there is no data in the application yet, we will first create 2 tasks using HTTP POST requests:
curl -i -X POST -H "Content-Type: application/json" \
-d '{"description": "Learn Coherence"}' \
http://localhost:8080/api/tasks
HTTP/1.1 200
As we get a 200
HTTP status response back, the first To Do task was created successfully. For good measure, let’s create a second task:
curl -i -X POST -H "Content-Type: application/json" \
-d '{"description": "Write an article"}' \
http://localhost:8080/api/tasks
HTTP/1.1 200
Now that we have created the second To Do as well, we will query for all currently existing tasks:
curl -i -X GET -H "Content-Type: application/json" \
http://localhost:8080/api/tasks
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 22 Sep 2021 21:37:02 GMT[{"createdAt":1632346354650,"completed":false,"id":"b769e4","description":"Write an article","createdAtDate":"2021-09-22T11:32:34.65"},{"createdAt":1632346614513,"completed":false,"id":"290d27","description":"Learn Coherence","createdAtDate":"2021-09-22T11:36:54.513"}]%
Lastly, lets mark a task as completed, just make sure you use a valid task id:
curl -i -X PUT -H "Content-Type: application/json" \
-d '{"completed": true}' \
http://localhost:8080/api/tasks/290d27
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 22 Sep 2021 21:38:37 GMT{"createdAt":1632346614513,"completed":true,"id":"290d27","description":"Learn Coherence","createdAtDate":"2021-09-22T11:36:54.513"}%
What’s Next?
With very little code, we were able to quickly put together a fully functional Coherence-powered Spring Boot app. But wait, that’s not all yet!
Please take a look at our more fully-featured To Do List Application located at https://github.com/coherence-community/todo-list-example.
REACT-based UI
It adds several more features. E.g. if you’re into graphical user interfaces (GUI), it provides a REACT-based UI.
Server-Sent Events (SSE)
In the full To Do application, the ToDoController
class will not only handle the REST calls but will also subscribe to Coherence Events using the @CoherenceEventListener
annotation, broadcasting any changes to connected clients using Server-Sent Events (SSE) via the SseService
.
GraphQL Support
The expanded To Do List application also provides an alternative API (besides REST) using GraphQL. Under the covers we use the GraphQL Spring Boot Starter. Please refer to the repository’s README file for additional information on how to interact with the GraphQL endpoint.
Further Reading
Furthermore, we invite you to compare the Spring code with the other articles in this series:
- Hello, Coherence — Now with Micronaut!
- Hello, Coherence (Helidon MicroProfile): Part 1, Part 2 & Part 3
Source Code
The source code for the full To Do List application is available on GitHub. The repository contains all three Java implementations, as well as a Node.js server implementation, so you have to go to the java/spring-server
directory for the Spring Boot implementation.
The source for the simple To Do List application we built as part of this article is available in a separate Git repository. Each commit lines up with the steps in this article.
Conclusion
The Oracle Coherence team provides first-class support for Spring Developers, substantially simplifying the user experience when using Oracle Coherence as part of Spring projects. At the same time, we maintain a similar developer experience across the various supported Java application frameworks, as shown by this article series.
Please feel free dig deeper into the To Do List application and by extension Coherence Spring. As always, if you have questions, please join our Slack channel or ask questions on Stack Overflow. If you see missing features or if you have any other suggestions for improvement please contact us, e.g. via Twitter @OracleCoherence or feel free to file a GitHub issue.