Skip to content

BuffaloBuffalo/boot-react

 
 

Repository files navigation

Spring boot and react starter (for Java!)

This is a fork of geowarin’s boot-react project which combines a a groovy based spring boot app with a react/flux front end. The goal of this project is to eventually strip out all the non-essentials (e.g redis, spring security, other react dependencies) so that it is a true bootstrapping project.

Many thanks to Geowarin for his excellent blog post and original repo. Without either this wouldn’t have been possible.

The quick start for development

The project is split into two sub projects: backend and frontend. backend is the spring boot java project, while frontend is the webpack-powered react proejct. Both projects are built with gradle.

First, setup npm dependencies in the react project:

./gradlew frontend:npmInstall

Then, start the backend project:

./gradlew backend:bootRun

Then, start the front end on a separate process

./gradlew frontend:start

You can also use npm start directly from the subproject if you wish.

Then, point your browser to localhost:3000

How it works in Development

This bundled setup will start two local servers-- one which serves the spring-boot server side dynamic content, and one which serves the react app(s). The React server has a proxy configured so that any requests to /api are proxied to localhost:8080 (e.g the spring boot server). Any other requests are serverd by the static index.html content.

How it works in production

When the application is built for standalone deployment, the backend project is configured to build the frontend project, and inclue the compiled assets into a JAR that is available on the classpath. Spring is configured (in SinglePageAppConfig) to map static resources to the compiled asssets on the classpath.

The rest

Be more productive than ever with this simple project that uses the spring dev tools and react transform for hot reloading.

Everything from backend to frontend will automatically hot reload.

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.

Developing

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:npmInstall

If you want to start both the frontend and the backend, the simplest is to use the webpack profile with the flag --spring.profiles.active=webpack. This will automatically start the frontend dev-server along with the spring boot application.

You can also run the frontend dev server separately with ./gradlew frontend:start or with npm start.

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

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

redis

Use a real redis connecting on localhost by default.

Yes

fake-redis

Uses a map to store sessions

Yes

Security

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.

Redux

This project uses Redux to handle state and actions. It is a simple library with very powerful dev tools.

I suggest you read the redux quick start to understand how to architecture you application and the difference between smart and dumb components.

Since the application is small, every component is connected to redux and can be considered a "smart component". Those are higher-order components, wrapped with the connect() method.

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'.

Router push state

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 you won’t see much complexity since we use a dev server that proxies requests to the index. However, this leads to additional complexity once the frontend is deployed inside the jar.

There is a whole class that you can remove if you choose to use memory history (no URL change) or hash history (/#/login, /#/private): SinglePageAppConfig

Running the tests

The check tasks will run the tests in both the frontend and the backend:

./gradlew check

You can run the backend/frontend tests only with:

./gradlew backend/frontend:test

To test the backend, we use a simple library that wraps spring mvc test. 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.

Shipping

This command will generate an optimized bundle and include it in the jar.

./gradlew clean assemble

You can then launch it with:

java -jar build/libs/boot-react-0.0.1-SNAPSHOT.jar

With 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.

Docker

The project can create a docker container.

Just run:

./gradlew backend:buildDocker

And 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 MB

You can then run it with:

docker run -p 8080:8080 boot-react/boot-react

You 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

Docker-compose

There is a simple docker-compose.yml in the root directory of the project. Once you have built the application image with ./gradlew backend:buildDocker, you can run:

docker-compose up -d

This will run the application together with a redis server.

About

A starter application with spring boot (java) and react

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 68.9%
  • Java 26.1%
  • HTML 5.0%