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:
User object will need 5 properties:
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
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
deleteById(). They're pretty standard CRUD methods, so I'll post them without explanation:
Next, modify or replace
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
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.
I recently blogged about a brand-new service in the Oracle Cloud - Database Tools. It's a safe, secure way to store your database credentials in the...
There's a brand new tool in town, and it's ready to make your life a whole lot easier if you work with Oracle DB in the cloud. It's called "Database Tools...
I have been spending a lot of time playing around with Oracle Advanced Queuing (AQ) lately and one of the things that has bothered me is the lack of a ...