Starter webapp using Spring Boot on the backend and React on the frontend, with Maven and Webpack as build tools, hot reloading on both sides and without xml configuration.
To run the app you just need to:
git clone https://github.com/dlizarra/spring-boot-react-webpack-starter.git ./starter
cd starter
mvn spring-boot:run
To check everything is running you can:
# Visit the homepage
http://localhost:8080
# Go to the sample REST endpoint
http://localhost:8080/api/users
# Login to the H2 console (JDBC URL: 'jdbc:h2:mem:embedded', user = 'h2')
http://localhost:8080/h2-console
The Java code is available at src/main/java
as usual, and the frontend files are in
src/main/frontend
.
Run StarterMain
class from your IDE.
Go to src/main/frontend
and run npm start
. (Run npm install
before that if it's the first time)
Now we should work with localhost:9090
(this is where we'll see our live changes reflected)
instead of localhost:8080
.
In the backend we make use of Spring DevTools to enable hot reloading, so every time we make a change in our files an application restart will be triggered automatically.
Keep in mind that Spring DevTools automatic restart only works if we run the
application by running the main method in our app, and not if for example we run
the app with maven with mvn spring-boot:run
.
In the frontend we use Webpack Dev Server hot module replacement
through the npm script start
. Once the script is running the Dev Server will be
watching for any changes on our frontend files.
This way we can be really productive since we don't have to worry about recompiling and deploying our server or client side code every time we make changes.
The project comes prepared for being used in three different environments plus another one for testing. We use Spring Profiles in combination with Boot feature for loading properties files by naming convention (application-<profile name>.properties).
You can find the profile constants in
StarterProfiles
and the properties files in src/main/resources
.
The database connections are configured in DatabaseConfig where we can find a working H2 embedded database connection for the default profile, and the staging and production configurations examples for working with an external database.
The project includes three base data repositories:
- ReadOnlyRepository: We can use this base repository when we want to make sure the application doesn't insert or update that type of entity, as it just exposes a set of methods to read entities.
- CustomCrudRepository: It's the same as the
CrudRepository
that Spring Data provides, but thefindOne
method in the custom version returns a Java 8Optional<T>
object instead of<T>
. It's just a small difference but it avoids having to override thefindOne
method in every repository to make it return anOptional
object. This repository is intended to be used when we don't need paging or sorting capabilities for that entity. - CustomJpaRepository: Again, it's there to provide the same funcionality as the Spring
JpaRepository
but returningOptional<T>
. We can extend this base repository if we want CRUD operations plus paging and sorting capabilities.
All the boilerplate for the initial Spring Security configuration is already created. These are they key classes:
- User, Role and RoleName which are populated by data.sql file for the default profile only.
- CustomUserDetails
- CustomUserDetailsService
- SecurityConfig with just very basic security rules.
The project includes Orika and it already has a class, OrikaBeanMapper, ready to be injected anywhere and be used to do any mapping. It will also scan the project on startup searching for custom mappers and components.
You can see how to use it in UserServiceImpl or in this sample project.
This, along with Lombok annotations for auto-generating getters, setters, toString methods and such, allows us to have much cleaner Entities and DTOs classes.
For unit testing we included Spring Test, JUnit, Mockito and AssertJ as well as an AbstractUnitTest class that we can extend to include the boilerplate annotations and configuration for every test. UserServiceTest can serve as an example.
To create integration tests we can extend AbstractIntegrationTest and make use of Spring @sql
annotation to run a databse script before every test, just like it's done in UserRepositoryTest.
The project is also ready to use Cobertura as a code coverage utility and Coveralls to show a nice graphical representation of the results, get a badge with the results, etc.
The only thing you need to do is to create an account in Coveralls.io and add your repo token key here in the pom.xml.
And if you want to use different tools you just need to remove the plugins from the pom.
We added ESLint preconfigured with Airbnb rules, which you can override and extend in .eslintrc.js file. To lint the code you can run npm run eslint
or configure your IDE/text editor to do so.
A travis.yml file is included with a minimal configuration just to use jdk 8, trigger the code analysis tool and deploy the app to Heroku using the api_key
in the file.
We also included a Heroku Procfile which declares the web
process type and the java command to run our app and specifies which Spring Profile we want to use.
mvn generate-resources spring-boot:run
The Maven goal generate-resources
will execute the frontend-maven-plugin to install Node
and Npm the first time, run npm install to download all the libraries that are not
present already and tell webpack to generate our bundle.js
. It's the equivalent of running npm run build
or npm start
on a terminal.
mvn spring-boot:run
In a second terminal:
cd src/main/frontend
npm run build
- Spring Boot
- Spring MVC
- Spring Data
- Spring Security
- Spring Test
- JUnit
- Mockito
- AssertJ
- Lombok
- Orika
- Maven