React Spring Boot Crud Example (2024)
In this article, we'll demonstrate how to create a Spring Boot Rest Api's with React.js for CRUD operations that consumes below Web APIs.
POST
- Create Employee RecordGET
- List all employeesGET
- Get employees by it's idPUT
- Update/Edit selected employee detailsDELETE
- Remove selected employee recordDELETE
- RemoveAll employees.
Spring Boot Crud Example Implementation
Create Spring Boot application
Create Spring Boot application from Spring Initializr.
Project Structure
Add Dependencies
Add below dependencies for Web - spring-boot-starter-web
, JPA - spring-boot-starter-data-jpa
and MYSQL - mysql-connector-java
in pom.xml
.
<?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.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.techgeeknext</groupId>
<artifactId>spring-boot-jpa-mysql-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-jpa-mysql-example</name>
<description>Spring Boot + JPA + MYSQL CRUD Example</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application Properties
Add database connection details in application.properties
file.
spring.datasource.url=jdbc:mysql://localhost/employeetestdb?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.platform=mysql
spring.datasource.initialization-mode=always
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
# spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
Data Model
Create Employee
class, contains id
, name
and
role
.
package com.techgeeknext.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "name")
private String name;
@Column(name = "role")
private String role;
}
JPA Repository
Create EmployeeRepository
interface that extends JpaRepository
.
JpaRepository
have default methods for which we don't have to provide it's
implementation,
save()
, findOne()
, findById()
, findAll()
, count()
,
delete()
, deleteById()
etc.
package com.techgeeknext.repository;
import com.techgeeknext.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
Refer Spring Boot JPA CRUD Example for full implementation.
Reactjs Crud Example Implementation
Create React Crud Project
Create the new React App using below command:
npx create-react-app react-crud-example
Project Structure
According to the project's use case or requirements, we can create files and folders.
Reactjs Dependencies
In React JS, all of the necessary dependencies are listed in the package.json
file. It
contains scripts to start, build, test and eject the React JS application.
{
"name": "react-crud-example",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
"bootstrap": "^5.1.3",
"react": "^18.2.0",
"react-bootstrap": "^2.4.0",
"react-dom": "^18.2.0",
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
React Hooks CRUD App - App component
- The App component (
App.js
) is the application's root container, which will importbootstrap.min.css
- Add
Routes
with default path page and all the navigation routes to the specific page. - For updating a particular employee record, pass the
id
parameter along with the edit page url.
import React from 'react';
import {Routes,Route,Navigate} from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import AddEmployee from './components/AddEmployee';
import EditEmployee from './components/EditEmployee';
import EmployeeDataTable from './components/EmployeeDataTable';
function App() {
return (
<div class="container card mb-4 box-shadow">
<div class="card-header">
<h4 class="my-0 font-weight-normal">TechGeekNext => React Crud Example</h4>
</div>
<Routes>
<Route path="/" element={<Navigate to="/read" />} />
<Route exact path="/create" element={<AddEmployee/>}/>
<Route exact path="/read" element={<EmployeeDataTable/>}/>
<Route path="/edit/:id" element={<EditEmployee/>}/>
</Routes>
</div>
);
}
export default App;
React Hooks CRUD Example - Employee Table with Edit/Delete
- Create the page
EmployeeDataTable.js
undersrc/components
- We can load the employee data using the
useEffect()
hook function, which uses axios get to execute GET rest endpoint and set the data into the employee state. - The
id
for the specific rows will be set while iterating the employee data; this will be helpful for editing and deleting the employee using axios. - To set the Employee Data, we'll make use of the
useState()
hook function.
import React, { useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import axios from "axios";
import editIcon from "./../assets/edit.png";
import deleteIcon from "./../assets/delete.JPG";
import "../App.css";
const EmployeeDataTable = () => {
const navigate = useNavigate();
const baseURL = "http://localhost:8080";
const [employees, setEmployees] = useState([]);
const setEmployeeData = () => {
axios.get(baseURL + "/employees").then((response) => {
setEmployees(response.data);
}).catch(error => {
alert("Error Ocurred while loading data:" + error);
});
}
useEffect(() => {
setEmployeeData();
}, []);
const removeEmployee = (id) => {
axios.delete(baseURL + "/employee/" + id).then((response) => {
alert("Employee record " + id + " deleted!");
setEmployeeData();
navigate('/read')
}).catch(error => {
alert("Error Ocurred in removeEmployee:" + error);
});
}
const removeAllEmployee = (id) => {
axios.delete(baseURL + "/employees").then((response) => {
alert("All Employees deleted!");
setEmployeeData();
navigate('/read')
}).catch(error => {
alert("Error Ocurred in removeEmployee:" + error);
});
}
return (
<div class="card-body">
<br>
</br>
<nav>
<button
className="btn btn-primary nav-item active"
onClick={() => navigate("/create")}>
Create New Employee
</button>
</nav>
<br></br>
<div className="col-md-6">
<h4>Employees List</h4>
<div class="container">
<div class="row">
<div class="col-12">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Role</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{
employees &&
employees.map((employee, index) => (
<tr>
<th scope="row">{employee.id}</th>
<td>{employee.name}</td>
<td>{employee.role}</td>
<td >
<Link to={"/edit/" + employee.id}><img src={editIcon} alt="Edit" width="50" height="30" title="Edit" />
</Link>
<button
onClick={() => removeEmployee(employee.id)} className="button"
> <img src={deleteIcon} alt="Remove" title="Remove" width="30" height="30" />
</button>
</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
</div>
<button className="btn btn-sm btn-danger"
onClick={() => removeAllEmployee()}>
Remove All
</button>
</div>
</div>
);
}
export default EmployeeDataTable;
React Crud Example - Add Employee
- Make a new page called
AddEmployee.js
that contains a form for adding new employee records. - Use the
useState()
hook function to store the employee values that were entered. - When a form is submitted, use the function to use axios to post the employee data to the POST rest endpoint.
- Navigate to the Employee table page to see the newly added record once the data has been added.
import React, { useState } from 'react';
import {useNavigate} from "react-router-dom";
import axios from "axios";
import { Form, Button, Container, Alert } from 'react-bootstrap';
const EmployeeForm = () => {
const baseURL = "http://localhost:8080/employee";
const navigate = useNavigate();
const [enteredName, setName] = useState('');
const [enteredRole, setRole] = useState('');
const nameChangeHandler = (event) => {
setName(event.target.value);
};
const roleChangeHandler = (event) => {
setRole(event.target.value);
};
const submitActionHandler = (event) => {
event.preventDefault();
axios
.post(baseURL, {
name: enteredName,
role: enteredRole
})
.then((response) => {
alert("Employee "+ enteredName +" added!");
navigate("/read");
}).catch(error => {
alert("error==="+error);
});
};
const cancelHandler = () =>{
//reset the values of input fields
setName('');
setRole('');
navigate("/read");
}
return(
<Alert variant='primary'>
<Container>
<Form onSubmit={submitActionHandler}>
<Form.Group controlId="form.Name">
<Form.Label>User Name</Form.Label>
<Form.Control type="text" value={enteredName} onChange={nameChangeHandler} placeholder="Enter User Name" required/>
</Form.Group>
<Form.Group controlId="form.Role">
<Form.Label>Role</Form.Label>
<Form.Control type="text" value={enteredRole} onChange={roleChangeHandler} placeholder="Enter Role" required/>
</Form.Group>
<br></br>
<Button type='submit'>Add Employee</Button>
<Button type='submit' onClick={()=>cancelHandler()}>Cancel</Button>
</Form>
</Container>
</Alert>
);
}
export default EmployeeForm;
Refer React Crud Example for full implementation.
Test Spring Boot + Reactjs CRUD Example
- Prerequisite : Start the Spring Boot JPA CRUD Example required for our React Crud Example.
- Use below command to install all the dependencies required for the project.
npm install # or yarn install
- Run the application by using below command:
npm start # or yarn start
- The application will open in browser at our configured port http://localhost:3000/ url.
Add Employee
Click on Create New Employee and provide employee name and role.List Employees
On the Home page, you will see all created employees with action to edit and delete.Edit Employee
Click on Edit icon from the employee table to edit the record from the Edit page.Remove Employee
Click on Remove icon from the employee table to remove the record.Remove All Employees
Click on Remove All button to remove all the employee records from the database table.
Download Source Code
The full source code for this article can be found below.
- Download source code - Spring Boot JPA CRUD Example
- Download source code -React Crud Example