Be more productive than ever with this simple project that uses the spring dev tools and react transform for hot reloading.
Everything: backend, frontend and styles will be hot reloaded automatically.
See my article for an in-depth explanation.
This project also sets up spring security and spring-sessions, which will automatically store your sessions in Redis, allowing you to scale on multiple servers.
Both the frontend and the backend are fully tested.
The groovy code is available in the backend sub-project.
The frontend sub-project contains the javascript code.
First, install the npm dependencies:
./gradlew frontend:npmInstallRun the backend with your IDE, the main method is in the BootReactApplication class.
In IntelliJ you can specify the active profiles in the run configuration.
Alternatively, you can use ./gradlew bootRun.
Then, run the frontend dev server separately with ./gradlew frontend:start or with npm start (recommended).
You will need npm 4.0+ to run the dev server.
The node version used by the gradle build is specified here. It is recommended that you use the same version in development and in your automated build.
In development you will have access to the awesome redux-dev-tools, which will allow you keep track of your application state and undo/redo every action at will.
Sessions are stored in Redis with spring-sessions. Spring-sessions allows you to transparently persist the HttpSession on Redis. This allows to distribute the load on multiple servers if you choose to.
The application relies on a stateless REST api.
When they authenticate, clients will be given a token.
They will save this token in their local storage and send it as an HTTP header (x-auth-token).
This allows the retrieval of the session data in Redis.
If you want to use a real redis, you can run the application with the redis profile.
If you want to simulate the retrieval of http sessions through headers, use the fake-redis profile.
This will save the sessions in a simple map (useful in dev).
If you choose to run the application with neither of those profile, the application will fallback to classic http sessions.
Summary:
| Profile | description | uses x-auth-token header? |
|---|---|---|
<none> |
Use classic HTTPSessions |
No. You won’t be able to use the API with a REST client |
|
Use a real redis connecting on localhost by default. |
Yes |
|
Uses a map to store sessions |
Yes |
If your run your project with gradle, the system properties won’t be passed on to Spring. See this issue for workarounds.
The simplest way to go is to specify active profiles in your IDE.
Check out the doc to learn more about profiles in Spring Boot.
The application is configured to work with Spring Security. It uses an in-memory authentication but you are free use other implementations or to roll your own.
This project uses Redux to handle state and actions. It is a simple library with very powerful dev tools.
Dan Abramov, the author of Redux, published a great Redux video tutorial.
I also suggest reading the redux quick start to understand how to architecture you application and the difference between smart and dumb components.
Since the application is small, most components are connected to redux and can be considered a "smart component".
Those are higher-order components, wrapped with the connect() method.
Small components are written using the stateless functional components syntax, i.e, those component are pure render components and only their props will have an impact on the resulting DOM.
To be able to write tests on smart components, we need to work on the non-wrapped components. That is why we export both the connected component by default and the non-connected component.
In the application we can import the connected component with import Component from 'component'.
In tests, we can import {Component} from 'component'.
The project uses react-router to handle routes. You can choose several modes to handles the router history. By default, the project uses the browser history, which creates the nicest URLs (/login, /private, etc.).
In development, we use a dev server that proxies requests to the index.
In production, we have to use a special resource handler to redirect all non-asset requests to the index.
You can remove it if you choose to use memory history (no URL change) or hash history (/#/login, /#/private).
We use stylus as a css preprocessor. We also leverage two stylus modules:
See examples of jeet here.
In development, the styles are included by webpack, which enables hot reloading. In production, we use the Extract Text Plugin to extract the css to a separate file.
The check tasks will run the tests in both the frontend and the backend:
./gradlew checkYou can run the backend/frontend tests only with:
./gradlew backend/frontend:testTo test the backend, we use a simple library that wraps spring mvc tests. It results in a better api for writing spock tests. See the auth-spec for an example.
To test the frontend, we use legit-test a simple library that allows writing fluent tests for React components.
This command will generate an optimized bundle and include it in the jar.
./gradlew clean assembleYou can then launch it with:
java -jar build/libs/boot-react-0.0.1-SNAPSHOT.jarWith spring boot 1.3, you can install the application as a linux service
NB: each application can be assembled with the assemble task so you can use frontend:assemble or backend:assemble.
The backend task depends on the frontend task.
The project can create a docker container.
Just run:
./gradlew backend:buildDockerAnd it will create a docker image named boot-react/boot-react.
> docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
boot-react/boot-react latest 5280d39f660f About a minute ago 138.9 MBYou can then run it with:
docker run -p 8080:8080 boot-react/boot-reactYou can also pass arguments to the application like this:
docker run -p 8080:8080 boot-react/boot-react --spring.profiles.active=redis --spring.redis.host=redis