So far in this series, we've set up our cloud for Kubernetes and Docker, got our Autonomous DB up and running and created our first microservice using Helidon and Hibernate. We're now ready to move on to creating the data model and persistence logic for our first microservice that will persist user data for our fictional social media application. If you're new to this series, I recommend catching up on the previous posts linked above so that you can follow along more easily as we move forward in the series.
Note: All of the code for this series is available on GitHub.
So our user microservice application has been configured and we're ready to create our model that represents our user objects. Create a new package called model
and within that a class called User.java
. We'll add properties that map to our database columns and some validation constraints to ensure our data is valid before we try to persist it. If you recall, our table was created with the following DDL script:
So our User
object will need 5 properties: id
, firstName
, lastName
, username
and createdOn
. The firstName
, lastName
and username
properties are non-nullable strings that have a max length of 50 characters. The ID
property will be a GUID and the createdOn
property is a timestamp. With that in mind, our properties and validation annotations on the User object will look like so:
The rest of the User object is standard boilerplate - nothing complicated.
The next step is to create a repository for our service persistence operations. Create a class in our user
package called UserRepository.java.
We'll inject our UserProvider that we created in the last post of this series to get our configuration into the repository and create our entity manager in the constructor:
Now add a validate()
method that we can use to make sure our users are valid before we try to save them.
We'll finish off the repository by adding methods for save()
, get()
, findAll()
, count()
and deleteById()
. They're pretty standard CRUD methods, so I'll post them without explanation:
Next, modify or replace GreetResource
with UserResource
. The resource file is where you define your service endpoints in Helidon. Start the resource out like so:
This tells Helidon to listen on the path of /users
for all methods in this class. We'll further define the path with each method. Before we get to the methods though, add a constructor where we'll use @Inject
to get an instance of our UserRepository
:
Now we can add paths to the resource. To define a default path, simply omit the @Path
annotation on the method. This will be called whenever http://localhost:8080/user
is called:
So defining each CRUD operation is a matter of creating resource methods and calling the appropriate repository methods.
To get a user by ID:
To list users:
To list users with pagination:
To delete a user by ID:
And finally, to save a user (note that we call validate()
before attempting the save, returning validation errors with a 422 Unprocessable Entity status if there are any):
We're now ready to compile and test our endpoints. Compile the service with mvn package
and then run the application with the following command. We need to pass in some properties here so the configuration is set properly, so refer to the previous post if you need to recall the path to your wallet files or the schema username or password. Substitute the path and credentials as appropriate:
Your app should now be up and running on port 8080 of your localhost. We can test out the endpoints like so at this point:
Get User Service Endpoint (returns 200 OK):
Save a new user (ID is returned in `Location` header):
Save a new user with invalid data (will return 422 and validation errors):
Get the new user:
List all users:
Delete a user
Confirm delete (same GET by ID will return 404)
And you've now created your first microservice using Helidon and Hibernate! In the next post we'll look at deploying the service to Docker and Kubernetes.