Generating an application using a Maven archetype
See how easy it is to use Maven to generate a Java application that demonstrates the concepts of CQRS and event sourcing.
Generating code or example applications can be a great way to get started with a new tool or concept.
In this guide you will learn how to generate a Java/Dropwizard application using a Maven archetype.
The generated application will be a fully functional backend service exposing a HTTP API according to the principles of CQRS. The API will use Serialized for storing events and projections so if you don't have an account yet, head over here to register one for free!
Generating the code
Start by opening a shell and type the following:
mvn archetype:generate \
-DarchetypeGroupId=io.serialized.archetype \
-DarchetypeArtifactId=serialized-dropwizard-archetype
You will be prompted for groupId
and artifactId
. Just enter com.example
and my-test-service
if you
can't come up with anything better.
The version
and package
can be skipped (keeping default) by pressing ENTER.
Finally, you will have choose if you want to keep the suggested names for the aggregateRoot
and the applicationName
.
Building the code
Build the code by changing to the new directory and execute Maven:
cd my-test-service
mvn verify
Wait for the code to build and the tests to complete.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Starting the service
Make sure to set/export the API keys to your Serialized project:
For Mac and Linux users:
export SERIALIZED_ACCESS_KEY=<your-access-key>
export SERIALIZED_SECRET_ACCESS_KEY=<your-secret-key>
or if you are on Windows:
set SERIALIZED_ACCESS_KEY=<your-access-key>
set SERIALIZED_SECRET_ACCESS_KEY=<your-secret-key>
Start the service:
java -jar target/my-test-service-1.0-SNAPSHOT.jar server config/config.yml
Calling the command API of your service
When we want to write/make state changes to our aggregate root we call the command API.
Note: We will assume you kept the suggested aggregate root name Game
in the following API calls.
Open a new shell and perform the following curl to send a start command:
curl -i http://localhost:8080/commands/start-game \
--header "Content-Type: application/json" \
--data '
{
"gameId": "3dbc7063-76d6-4df2-8ab4-72d1f897563b"
}
'
The expected response should be something like this:
HTTP/1.1 201 Created
Location: http://localhost:8080/queries/games/3dbc7063-76d6-4df2-8ab4-72d1f897563b
Content-Length: 0
Note that the Location header points to where we can access the projected read-model via the query API.
The start command results in a stored event called GameStarted was stored in Serialized. Browse to the Console and have a look at it!
Calling the query API of your service
When we want to get our data, we use the query API.
Try to get the projected game state using this simple GET request:
curl -i http://localhost:8080/queries/games/3dbc7063-76d6-4df2-8ab4-72d1f897563b
The expected response should be something like this:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Content-Length: 28
{
"status" : "STARTED"
}
Make a second state change by sending another command to the API
Let's send a finish command to put our aggregate root into its end-state:
curl -i http://localhost:8080/commands/finish-game \
--header "Content-Type: application/json" \
--data '
{
"gameId": "3dbc7063-76d6-4df2-8ab4-72d1f897563b"
}
'
Verify the change using the query API
Do the same GET request as before:
curl -i http://localhost:8080/queries/games/3dbc7063-76d6-4df2-8ab4-72d1f897563b
The status field should now say FINISHED.
Extending the service
Your are now ready to add your own functionality to your service! Try to add some fields to existing commands/events, introduce new commands or play around with the projections.
Check out our sample code for inspiration!
More info regarding the Java Client can be found on our site.
Detailed info regarding the API:s can be found in the official documentation.