Test Driven Web Application Development with Spring & React

I have been working on my course about Test Driven Web Application Development with Spring & React for a long time. Finally it’s completed and published on Udemy.

In this course, we are building an actual web application and while doing that, we will see how we can use Spring Framework and React JS in a web app and also we will learn how to apply Test Driven Development methodology.

You can use this link https://www.udemy.com/course/test-driven-web-application-development-with-spring-react/?referralCode=5EE4FA2E84E78941F649 to access the course.

Please share with anyone who are interested in learning Full Stack Web application development and who wants to see Test Driven Development in action.

Spring Data Specifications

This tutorial is to show how specifications are used with spring data jpa.
We have this entity

And what we want to do on front end side is to filter the People based on the values of fields.
e.g All people with brown eyecolor and age is older than 25 and who has profile picture.

Since this query parameters can be changed dynamically, we need to come up with a flexible query generation solution which is JPA’s query builders Specification approach.

Specification provides a flexible configurable query generation logic for us. An example Specification is as follows

We are creating specification based on hasPicture condition which would lead query to check if Person picture is null or not.

The Specification implements the method with parameters Root root, CriteriaQuery<?> query, CriteriaBuilder cb
Person_ seen above is the meta model of our entity which is required for Query building. You can check this article about meta model in hibernate.

Our controller takes user query parameters as follows

Filter is the object that represent the RequestVariables.

And the service logic is as follows

So in our service logic we check if we are receiving any filter param and if so, we are creating specifications for each of them and combining it together in the end and asking dao to pull the data based on that specification logic.
The dao must implement JpaSpecificationExecutor to handle specification related queries.

The sample project codes are here

Happy specificating! 🙂

Spring TDD – Test Driven Development

In this blog, I’m sharing an example project to show unit and integration test with Spring.

We have a web service for car. Here is the entity

And lets say we have a Dao for this entity as follows

Spring provides a custom test configuration for testing this Dao class. All you have to do is use @DataJpaTest annotation in your test class.

@RunWith(SpringRunner.class) -> this part is required to use @Autowired or other spring related annotations to be processed.

TestEntityManager is used as a replacement of JPA’s EntityManager for executing SQL queries in test mode.
DataJpaTest will create an in-memory database for the runtime test environment.
By Default this mode is @Transactional which means after each test, the test db will be rolledback.

After completing the Dao test, we can go to next step which is unit test for @Service class.

First of all, make sure to use Constructor injection, not field injection. This will be helpful when we write unit tests for this class.
This is the part of test class

We are using @MockBean annotation for CarDao. Our intention here is, not running the whole Spring App but just run the CarService only. To accomplish that, we create the CarService instance and mock the all possible dependencies (for our case, it s just CarDao but it could be more than that).

With Mockito, we are mocking the behavior of carDao for specific methods and testing them through CarService methods. So we verify our service methods are working as we expected.

After completing the unit testing for the service class, we can do the integration testing of RestController.

This is our rest controller

And this is the integration test

The main difference here is the @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) annotation. This is starting the app in random port.
We are using TestRestTemplate as client to execute REST requests.
Since this test code is also running in spring context, we can inject CarDao here for inserting dummy data to our test database and pull it through rest calls.

I’d highly recommend to use a test profile with test environment database configuration in it to make sure you are in control with your application status during testing.
All you have to do is to add @ActiveProfiles("your-test-profile-name") to your test class.

In integration test, the test methods are not in transactional mode which means they will not be rolled back after each test execution. Therefore you should be careful about not changing the applications state between tests. Since Junit is not running the tests in order (which can be configured to run in order but I wouldn’t suggest it), if any test would be leaving unexpected data in db, it may break other tests. So make sure you return to your original state after the test is completed. You can use @Transactional annotation. Or you can add a method to clear the database after each test run and you make sure it with @After annotation.

Spring TDD code is here

Happy testings!

Spring Boot with Docker

In this project there is a simple rest backend which will be running inside docker container.
We’ll have multiple instances of this application and we’ll be using HAProxy for load balancing for the backend apps.

The network diagram is as follows

LBDiagram

The project source code can be found at this github link.

The backend app is a single rest controller (/hello) which generates json response with hello message.

In the controller, environment value of message is being used. This variable will be set by docker commands later. It’s just for confirmation of load balancing.

After running mvn package in this project folder, helloserver.jar file will be generated inside the target folder. This jar will be copied to docker image.
This is the Dockerfile of spring boot application.

It’s copying the jar, setting the port to be exposed and setting the run command of the application.

This folder contains the Dockerfile and haproxy.cfg files. We’ll be building an image for haproxy with our custom configuration of docker network.

This is the Dockerfile for haproxy

This will be building a new image with the copy of haproxy.cfg with the haproxy:1.5 image.

This is the config file

bind *:80 – this is setting public network port for haproxy
server server1 hello1:8080 check – server is config keyword. server1 is the internal name . hello1:8080 is the address and port of the backend server. check is for the health check for this server
server server2 hello2:8080 check – same config for server 2 which will be called as hello2

hello1:8080 and hello2:8080 will be resolved by docker’s networking capability.

here’s how to build images
This is for the spring boot image
\helloserver> docker build -t hello/server .

and this is for the haproxy
\helloserver\haproxy> docker build -t hello/haproxy .
You should be seeing these images in your docker image list
\helloserver\haproxy> docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
 hello/haproxy latest c8d6f80893a7 9 seconds ago 136.2 MB
 hello/server latest e589ccbd5a65 52 seconds ago 195.5 MB

Create a custom network for docker
> docker network create hellonetwork

And run the images.
Since the haproxy is configured with servernames (hello1, etc) during initialization, it’ll try to discover those devices. But if there is no running device with name “hello1” in docker, haproxy will not find it and fail to start. To eliminate this problem, run the haproxy after the backend servers are started.

start the backend instance
> docker run -d --net hellonetwork -e message=Server1 --name hello1 hello/server
-d – the daemon mode
--net – setting the net to be used for that image (hellonetwork)
-e – setting environment variable (message=Server1) – rest controller will be reading this parameter
--name – setting the name for this image (hello1)

start another instance from same image with different name and message
> docker run -d --net hellonetwork -e message=Server2 --name hello2 hello/server

since both of the backend servers are up we can start the haproxy

> docker run -d --net hellonetwork -p 80:80 --name haproxy hello/haproxy
-p – the docker will expose the internal port 80 to external 80, so we’ll access to haproxy through 80

the environment is ready to test
> docker-machine ip
192.168.99.100

Open a browser and go to http://192.168.99.100/hello . Refresh it couple of times. You’ll see the response will be {“content”:”hello from server Server1″} or {“content”:”hello from server Server2″}

Thanks

Injecting custom object to controller in Spring Boot

In Spring, you can inject your custom object to the controller methods like this

Here are the steps of this implementation.

In my sample project I have ClientRequest object which contains incoming request related variables.

These variables are basically taken from the HttpServletRequest object. So we could inject HttpServletRequest instead of ClientRequest and would generate the same content, but that’s not the point. In your project, you may need custom objects which would need additional object dependencies or you may want to centralize the object creation algorithm instead of repeating it in every controller method.

Next, we implement ClientRequestArgumentResolver which implements HandlerMethodArgumentResolver.

ClientRequest object is created in the resolveArgument(...) method.

All we have to do is add a new Configuration class to our project and add this ArgumentResolver to Spring’s argumentResolvers List.

Now we can inject ClientRequest to our controller methods.

You can check the sample project in my github.
And the objects are
ClientRequest
ClientRequestArgumentResolver
ClientRequestContext
Controller is here.

The data is displayed in this html file.

Run the app and open the page http://localhost:8080/request

Have fun!.

Returning user requested variables with Spring

When implementing a REST API, you may want to provide flexibility for users about filtering the content based on their requests.

when requesting GET /movies/1

and when user sets fields, GET /movies/1?fields=year,subject,director the result would be

Implementation of this behavior is very similar to my previous tutorial about Role Based Content in Spring. I’m using the same sample project for this tutorial also.

We have this Movie entity.

And we have this movie controller.

We are injecting @AuthenticatedUser TutorialUser user (Check here for the details of this implemantation) and @RequestParam(value = "fields", defaultValue = raw) String rawFields to our controller method.

Since we’ll be doing variable filtering, the method is returning MappingJacksonValue. In getMappingJacksonValue method, comparing the variables coming with the fields parameter to the existing variable List of corresponding user role. Creating the String array for the matching variables and setting it as a filter and returning the result.

So this code is checking both user role and the fields in the request before generating the response content.

Since user/user has limited variable set, executing GET /movies/1?fields=actor,actress,year would result following json with only year in it.

If year is removed from request, GET /movies/1?fields=actor,actress the response would be

You can check the sample project at my github.

I’m using Postman when I want to play with the requests. Postman scripts for this application is here. You can just import and use them. But if you would like to use another tool, here is the api doc

user/pass = admin/admin and user/user

base url: http://localhost:8080
GET /movies // gets list of movies
GET /movies?fields=id,year… // return the specified fields in the list of movies
GET /movies/{id} //gets the movie with specified id
GET /movies/{id}?fields=id,year… // return the specified fields of the specified movie

POST /login?username=admin&password=admin

Have fun!

Returning role based content in Spring Rest Controller

When implementing a rest backend, you may be looking for a way to hide the variables of an entity based on the logged in user’s role.

Here’s a sample entity. Movie

It has id, year, length, title, subject, actor, actress, director variables.

And in my application, I have two user roles which are admin and user.

I want admin to see all variables of the Movie. But I want user to see only year, title, subject variables.

Here’s how to filter variables..

In the Movie entity we have @JsonFilter annotation. This is a Jackson feature. You can check here for more details about it.

This entity is processed in the controller as follows.

Our controller method (getMovies) at Line 12 is executed when we request GET /movies from browser.
This method is returning MappingJacksonValue in the response.

There are two String arrays which contain the set of variable names for the limited version and the all version.

In controller method, we inject the current logged. @AuthenticatedUser TutorialUser user . Check here for the details of this implemantation.

All we do here is (Line 16 – 17) select the String array based on user role, and set as a filter for our MappingJacksonValue object.

You can check the sample project at my github.

Run the app. Open the page at http://localhost:8080
user/pass = admin/admin and user/user

If you log in with admin, you’ll see this page where all the variables exist in the table.
admin_list

when you log in with user, you’ll see
user_list

Have fun!.

Getting current Authenticated User in Spring Rest controller

When you need to get the active logged in user in your controller, the most common way would be injecting Principal to your controller methods.

But when you need this to be done in multiple methods, you may be looking for a cleaner approach like injecting the exact User instead of Principal object.

To inject your user object (e.g. TutorialUser) follow these steps.
Make your TutorialUser to implement org.springframework.security.core.userdetails.UserDetails

Create the annotation you want.
Make sure to add the @AuthenticationPrincipal annotation. Otherwise it won’t work.

Then you can use this annotation with your User object in your controllers.

You can check an example code at my github page.

Android Toolbar Menu Extension

I’ve implemented a custom view to expand the Android Toolbar’s existing menu space.
Here’s how it works.

menuextension

Expanding the existing Toolbar’s menu functionality is a good way if you are dealing with too many sub menu items in your application.

Take a look at my github

There is also a demo app at google play.

Lightweight single JAR application as a REST backend server

This tutorial will be covering wide range of REST server side topics. Final result will be a simple, lightweight, single jar application works as a REST backend.
Jetty will be used as Web Server.
Jersey will be handling the rest requests.
Data will be stored in memory H2 database.
Hibernate is used to store/retrieve entites to/from H2 database.

You can check the source code of this project on github.

This is the project structure

Project Structure

The main method is in App.java.
Rest controllers are in com.bafoly.tutorials.minimalrest.controller package
Entities are under com.bafoly.tutorials.minimalrest.entity package and the EntityManager instance is under com.bafoly.tutorials.minimalrest.jpa

Here’s dependencies in the pom.xml. The full version is here.

main method of App.java.

This is basically tying the components together. It starts the web interface of H2 database (Line 5), makes the configuration and starts the Jetty Server (Lines 8-9-12-13 and 28-29) and adds the Jersey Servlet (Line 16) to jetty configuration.
Jersey will scan all the JAX RS annotated classes under the package com.bafoly.tutorials.minimalrest at Line 19.
Jersey will be using Jackson for JSON converter. (Line 21)

You can check here for some examples about Embedded Jetty.

This server will be listenning the port 7070 for http requests.
For Web interface of H2 database, the port is 7071. It can be accessed from http://localhost:7071
You can find further details about H2 database here.


JPA part

This application has two Entities.
Author and Book

The full version of Author is here and Book is here.

Book entity has Genre enum which is persisted to database as String inside Book table.

If you are not familiar with the JPA (Java Persistence API) please take a look at the official documentation. Also it’d be good if you check this page for JPA in standalone applications.
@Entity, @Id, @GeneratedValue, @OneToMany and @ManyToOne annotations are related to JPA. Hibernate checks all the entities in the project and creates tables based on these annotations.

@JsonView

@JsonView is Jackson feature used for generating subset of an entity during serialization/deserialization. For details about it, look here. These views are defined inside the View.java
Let’s say the server will generate a response containing the Author entity
If the controller method is tagged with View.Base.class, then the response JSON will contain Author’s only id, name and lastname variables.
If the controller method is tagged with View.AuthorExtended.class, since the AuthorExtended extends the Base interface, the response will contain the variables tagged with both Base and AuthorExtended. So plus to the id, name and lastname variables, also books will be added to the response. And when the books are added to JSON, Jackson will take the variables which are tagged with View.Base.class or View.AuthorExtended.class from the Book entity.

For JPA configuration there is the persistence.xml under META-INF folder. Full version is here.

minimalRest is a given name for this persistence unit. It will be used during EntityManager creation.
Since this is a standalone application (which means it’ll not be running on JEE Application Server like JBOSS etc) the transactions will be handled locally. To do that transaction-type="RESOURCE_LOCAL" is added. Hibernate is used as provider. The property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" triggers H2 to run in Memory and it will create the database test for the application.
To use JPA in the application, EntityManager must be created. The following code shows that part.

persistence.xml is being read at this point. It checks for minimalRest and reads all the properties of that unit then creates an instance of EntityManager.
This code is in EntityManagerUtil.java. Full version is here.

In the main method of App.java there is generateInitialContent(); which is something like this.

This is how the JPA persists entities to database. Same actions will be used in the REST Controllers.


REST Controllers

There are AuthorController and BookController.
If you are not familiar with the concept, you can check Jersey’s this page for more details. The full versions of AuthorController is here and BookController is here.
A short part from AuthorController is like this.

The controller contains several methods to serve to the HTTP Requests (GET, POST, PUT, DELETE).
The @Path defines how to reach to this controller.
When you execute GET /author, that request will be processed in this method.
@Produces makes this method to generate the response body with specified type, which is JSON for this case. Remember that at the main method of App.java, during the jersey initialization part, for JSON serialization Jackson was set. If it wouldn’t be done there, current method would be throwing exception since it would not be able to convert the Object to JSON.
Other than Jersey’s page, check here for more details about Java’s Rest Service Standard JAX-RS.


Running the app

When you run the app, the database will be loaded with initial data.
You can access to H2 at http://localhost:7071
You’ll be seeing following content.
h2console

And of course you can access to these data through REST interface by executing HTTP methods.

I’m using Postman when I want to play with the requests. Postman scripts for this application is here. You can just import and use them. But if you would like to use another tool, here is the api doc
base url: http://localhost:7070
GET /author – list of authors
GET /author/{{id}} – details of author
POST /author – add a new author
PUT /author/{{id}} – update the author
DELETE /author/{{id}} – delete the author

GET /book – list of books
GET /book/{{id}} – details of book
POST /book – add book
POST /author/{{id}}/book – post book to author
PUT /book/{{id}} – update the book
DELETE /book/{{id}} – delete the book

Have fun!