Spring Boot and React: Happily Ever After
Learn how to develop a full-stack web application using Spring Boot and React.
Join the DZone community and get the full member experience.
Join For FreeSo you have mastered Spring Boot and started toying around with React. Now you want React to talk to your Boot app as your backend API. That's fabulous. You probably already know how to do this, but there is a kicker. You want to package them and start both of them as just one project.
Well, you're in luck! This post is going to take a couple of simple projects and combine them into one. Lace up your boots and get ready to React!
Wedding Boots
First off, we have to get the Spring Boot app up and running. Here are the steps. All these steps are using the STS IDE. In my opinion, when working on Boot it is easiest to use the tool recommended by Spring. If you are an IntelliJ user or something else, feel free to do what you like. If you already have an application you would like to use, then skip this section.
- Create a New > Spring Starter Project
- Give your project a name. Then select if you want Gradle or Maven. We'll use Maven for this article.
- Next, we'll choose "Web" and "Jersey". This keeps what we want to do really simple. There are no database needs at this point or any other shenanigans.
After the build, it should look something like this.
- We will create a Model object for our JSON object.
public class Message { private String name; public Message(String name) { this.name = name + ", thanks so much for clicking the button! You really do love me!"; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
- Next, add a mew Java class that we'll call
DemoRestController
. Paste this in:
import com.example.model.Message;
@RestController
public class DemoRestController {
@RequestMapping("/greeting")
public Message greeting(@RequestParam(value="name", defaultValue="World") String name) {
return new Message(name);
}
}
Alright, we've done what we need to do from a Spring Boot perspective.
Be sure that the Boot Project runs. From STS you can use the Boot Dashboard and just run it, or you can right click and choose "Run as Java Application." Also if using Maven, you can use mvn spring-boot:run
. Check http://localhost:8080?name=Bob
. It should produce a JSON object.
{"name":"John, thanks so much for clicking the button..."}
React to Love
- Have npm and yarn installed.
- Open a command line and navigate to BootReactStarter directory and run
yarn create react-app frontend
- Grab a cold one and wait for everything to install. It'll take a bit.
When it is done, you should see something like this:
So let's do what it says!
A browser window should load to http://localhost:3000 and give you the basic React page like so:
It is time to make a couple of adjustments. In the front-end directory, change the package.json file. We will be adding a "proxy" so that any requests we add will go to http://localhost:8080 (our Spring Boot app).
`"proxy": "http://localhost:8080",`
Restart the React application.
Next, we'll add in an input box and button to demonstrate our call to the API. Paste this into App.js:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
state = {
isLoading: false,
greeting: ""
};
sayHello = async (event) => {
event.preventDefault();
let response = await fetch('/greeting?name=' + this.state.greeting);
let body = await response.json();
this.setState({ greeting: body.name, isLoading: false, isGreetingVisible: '' });
}
updateName = (event) => {
event.preventDefault();
this.setState({greeting: event.target.value, isLoading: false});
}
render() {
const {greeting, isLoading} = this.state;
if (isLoading) {
return
Loading...
;
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<div className="App-intro">
<input onChange={(event)=>this.updateName(event)} placeholder="Enter Your Name"></input>
<button onClick={(event)=>this.sayHello(event)}>Please Click Me!</button>
<h2 style={{visibility: this.isGreetingVisible}}>Hello {this.state.greeting}</h2>
</div>
</header>
</div>
);
}
}
export default App;`
If you're already running the React server, it will automatically reload. Otherwise, start it again.
With both React and Boot running, fill in a name and click the button. It should look something like this.
The click of the button makes a request to our Boot backend and returns a string appended to the name entered. This is a simplistic request, but it demonstrates how the two can work together.
Awesome, well done! Now it's time to marry the two together. We need to change the pom.xml by adding in these values:
<properties>
...
<frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>
<node.version>v10.13.0</node.version>
<yarn.version>v1.12.1</yarn.version>
...
</properties>
And adding in profiles:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-classes</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/static</outputDirectory>
<resources>
<resource>
<directory>frontend/build</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<workingDirectory>frontend</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<yarnVersion>${yarn.version}</yarnVersion>
</configuration>
</execution>
<execution>
<id>yarn install</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>generate-resources</phase>
</execution>
<execution>
<id>yarn test</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>test</phase>
<configuration>
<arguments>test</arguments>
<environmentVariables>
<CI>true</CI>
</environmentVariables>
</configuration>
</execution>
<execution>
<id>yarn build</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
Make sure you have stopped both React and Boot if they were running individually. Go back to your command line and start with the following:
`mvnw spring-boot: run -Pprod`
This will again take some time as it is packaging everything up into one file. It will download everything again so you can go water the garden or get some pretzels to go with that cold one you picked up.
Once it is up and running, open a browser and go to http://localhost:8080. Your React app should be displayed. Voila! You have run your React app via Spring Boot.
Conclusion
We have created a standalone Spring Boot application and a standalone React application. Once they were working on their own, we put them together into one runnable jar. This can make deployment onto whatever system a breeze.
This project is far from a Production-ready release, but you can see how easy this can make development when dealing with both of these game-changing technologies. Have fun developing as a full-stack developer!
References
- https://github.com/eirslett/frontend-maven-plugin
- https://spring.io/projects/spring-boot
- https://reactjs.org/
If you enjoyed this article and want to learn more about React, check out this collection of tutorials and articles on all things React.
Published at DZone with permission of Matt McCandless, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Top 10 Engineering KPIs Technical Leaders Should Know
-
Tech Hiring: Trends, Predictions, and Strategies for Success
-
Knowing and Valuing Apache Kafka’s ISR (In-Sync Replicas)
-
Event-Driven Architecture Using Serverless Technologies
Comments