React Spring Boot Example



In this tutorial, we will create a very simple "single page application" using react as front end and spring boot as backend.

Prerequisites

  • Basic familiarity with HTML & CSS.
  • Basic knowledge of JavaScript and programming.
  • Spring Boot Basics
  • Node.js and npm installed globally.

What we will build?

We will build a simple REST API using spring boot and we will consume REST API using React JS client application.

Develop Spring Boot Backend Application

1. Create a Spring Boot Application

There are many ways to create a Spring Boot application. You can refer below articles to create a Spring Boot application.

2. Add maven dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/>
        <!-- lookup parent from repository -->
    </parent>
    <groupId>net.javaguides</groupId>
    <artifactId>springboot-reactjs-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-reactjs-example</name>
    <description>Demo project for Spring Boot and React JS</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. Create Simple REST API - /books

Let's create a BookController class and add the following code to it:
package net.javaguides.springboot;

import java.util.Arrays;
import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BookController {

    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/books")
    public List < Book > getBooks() {
        return Arrays.asList(new Book(1, "Core Java"), new Book(2, "Effective Java"), new Book(3, "Head First Java"));
    }
}

class Book {
    private int id;
    private String bookName;

    public Book(int id, String bookName) {
        super();
        this.id = id;
        this.bookName = bookName;
    }

    public int getId() {
        return id;
    }

    public String getBookName() {
        return bookName;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
}

4. Run Spring Boot Application and Test Rest API

Let's run this spring boot application from IDE -> Right-click -> Run As -> Java Application:
package net.javaguides.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootReactjsExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootReactjsExampleApplication.class, args);
    }
}
Hit this "http://localhost:8080/books" link in a browser will a populate list of books as JSON.

Build React JS Frontend Application

Let's go ahead and create React application to consume /books REST API.

1 - Create a React UI with Create React App

The Create React App CLI tool is an officially supported way to create single-page React applications. It offers a modern build setup with no configuration.
To create a new app, you may choose one of the following methods:

Using npx

npx create-react-app react-frontend

Using npm

npm init react-app react-frontend
npm init is available in npm 6+

Using Yarn

yarn create react-app react-frontend
Running any of these commands will create a directory called react-frontend inside the current folder. Inside that directory, it will generate the initial project structure and install the transitive dependencies:
react-frontend
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    ├── logo.svg
    └── serviceWorker.js
Let's explore important files and folders of the react project.
For the project to build, these files must exist with exact filenames:
  • public/index.html is the page template;
  • src/index.js is the JavaScript entry point. 
You can delete or rename the other files Let's quickly explore project structure.

package.json - The package.json file contains all the required dependencies for our React JS project. Most importantly, you can check the current version of the React that you are using. It has all the scripts to start, build, and eject our React app.
public folder - The public folder contains index.html. As react is used to build a single page application, we have this single HTML file to render all our components. Basically, it's an HTML template. It has a div element with id as root and all our components are rendered in this div with index.html as a single page for the complete react app.
src folder- In this folder, we have all the global javascript and CSS files. All the different components that we will be building, sit here.
index.js - This is the top renderer of your react app. 
node_modules - All the packages installed by NPM or Yarn will reside inside the node_modules folder.
App.js - The App.js file contains the definition of our App component which actually gets rendered in the browser and this is the root component.

2 - Adding Bootstrap in React Using NPM

Open a new terminal window, navigate to your project's folder, and run the following command:
$ npm install bootstrap --save
After installing the bootstrap package, you will need to import it in your React app entry file.
Open the src/index.js file and add the following code:
import 'bootstrap/dist/css/bootstrap.min.css';

src/index.js

Here is the complete code for index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

3. React Service Component - REST API Call

For our API calls, we will be using Axios. Below is the npm command to install Axios.
npm add axios
Below is the APIService.js service implementation to make our HTTP REST call via Axios. Our backend books endpoint is available at http://localhost:8080/books
import axios from 'axios';

const BOOK_API_REST_URL = "http://localhost:8080/books";

class APIService {
    
    getBooks(){
        return axios.get(BOOK_API_REST_URL);
    }

}

export default new APIService();
Make sure that you create an object of APIService class export it as:
export default new APIService();

4. Develop a React Component

Components are the building blocks of our whole react app. They are like functions that accept inputs in terms of props, state, and outputs a UI that is rendered in the browser. They are reusable and composable.
React components can be either a function component or a class component. In this example, we are going to use the class component.
Let's create a BookComponent.js file and add the following code to it.
import React from 'react'
import APIService from '../service/APIService'

export default class BookComponent extends React.Component {

    constructor(props) {
        super(props)
    
        this.state = {
             books: []
        }
        this.loadBooks = this.loadBooks.bind(this);
    }
    
    componentDidMount(){
        this.loadBooks();
    }

    loadBooks(){
        APIService.getBooks().then((res) => {
            console.log(res);
           this.setState({books : res.data})
        });
    }


    render() {
        return (
            <div>
                <h2 className="text-center">Book Details</h2>
                <table className="table table-striped">
                    <thead>
                        <tr>
                            <th>Book Id</th>
                            <th>Book Name</th>
                        </tr>
                    </thead>
                    <tbody>
                        {
                            this.state.books.map(book =>
                                    <tr key={book.id}>
                                        <td>{book.id}</td>
                                        <td>{book.bookName}</td>
                                    </tr>
                            )
                        }
                    </tbody>
                </table>
            </div>
        )
    }
}
Let's understand the above code step by step.
  • constructor() - The constructor () is invoked before the component is mounted. In the constructor, we have declared our state variables and bind the different methods so that they are accessible from the state inside of the render() method.
  • componentDidMount() - The componentDidMount() is called as soon as the component is mounted and ready. 
  • render() - The render() method is the most used lifecycle method. The render() method that actually outputs HTML to the DOM.
We are using the map operator to loop over our book list and create the view like:
{
 this.state.books.map(book =>
   <tr key={book.id}>
    <td>{book.id}</td>
    <td>{book.bookName}</td>
   </tr>
 )
}

5. App.js

In the previous step, we have created BookComponent so let's go ahead add BookComponent to App component:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import BookComponent from './components/BookComponent';

function App() {
  return (
    <div>
      <header className="container">
         <BookComponent />
      </header>
    </div>
  );
}

export default App;

6. Run React App

Use below command to start the project:
npm start
Use yarn to start the project:
yarn start
Runs the app in development mode. Open http://localhost:3000 to view it in the browser.

Comments