├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── loizenai
│ │ └── springboot
│ │ └── reactjs
│ │ ├── Initializer.java
│ │ ├── SpringBootCrudReactApplication.java
│ │ ├── controller
│ │ └── CustomerController.java
│ │ ├── model
│ │ └── Customer.java
│ │ └── repository
│ │ └── CustomerRepository.java
└── resources
│ └── application.properties
└── test
└── java
└── com
└── loizenai
└── springboot
└── reactjs
└── SpringBootCrudReactApplicationTests.java
/README.md:
--------------------------------------------------------------------------------
1 | # SpringBoot + React + PostgreSQL: SpringBoot React.js CRUD Example
2 |
3 | 
4 |
5 | In the tutorial, I introduce how to build an “SpringBoot React.js CRUD PostgreSQL Example” project with the help of SpringData JPA for POST/GET/PUT/DELETE requests with step by step coding examples:
6 |
7 | – SpringBoot project produces CRUD RestAPIs with PostgreSQL database using the supporting of Spring Data JPA.
8 | – React.js project will consume the SpringBoot CRUD RestAPIs by Ajax then show up on Reactjs component’s views.
9 |
10 | List to do:
11 |
12 | – I draw a fullstack overview Diagram Architecture from React.js Frontend to PostgreSQL database through SpringBoot RestAPI backend.
13 | – Develop SpringBoot CRUD RestAPIs with the supporting of SpringWeb Framework.
14 | – Implement Reactjs CRUD application with Ajax fetching APIs to do CRUD request (Post/Get/Put/Delete) to SpringBoot Backend APIs.
15 | – I create a testsuite with a number of integrative testcases with CRUD RestAPI requests from Reactjs to do CRUD requests to SpringBoot RestAPIs Server and save/retrieve data to PostgreSQL database.
16 |
17 | ## Overall Architecture System: Reactjs + SpringBoot + PostgreSQL
18 |
19 | 
20 |
21 | - We build a backend: SpringBoot CRUD Application with PostgreSQL that provides RestAPIs for POST/GET/PUT/DELETE data entities and store them in PostgreSQL database.
22 | - We implement React.js CRUD Application that use Ajax to interact (call/receive requests) with SpringBoot CRUD application and display corresponding data in Reactjs Component.
23 |
24 | ## SpringBoot PostgreSQL CRUD Design Application
25 |
26 | 
27 |
28 | I build a SpringBoot project that handle all Post/Get/Put/Delete requests from RestClient and do CRUD operations to PostgreSQL database to save/retrieve/update and delete entity from PostgreSQL and returns back to Restclient the corresponding messages.
29 |
30 | We build a SpringBoot project with 2 layers:
31 | – SpringJPA Repository is used to interact with PostgreSQL database by a set of CRUD operations.
32 | – RestController layer is a web layer for SpringBoot project, it will directly handle all incomming requests and do the corressponding responses to the calling client.
33 |
34 | ## Reactjs CRUD Application Design
35 |
36 | 
37 |
38 | – Reactjs CRUD Application is designed with 2 main layers:
39 |
40 | React.js components let you split the UI into independent, reusable pieces, and think about each piece in isolation.
41 | Ajax is used by Reactjs component to fetch (post/put/get/delete) data from remote restapi by http request
42 |
43 | Reactjs CRUD Application defines 5 components:
44 |
45 | - Home.js is used serve as the landing page for your app.
46 | - AppNavbar.js is used to establish a common UI feature between components.
47 | - CustomerList.js is used to show all customers in the web-page
48 | - CustomerEdit.js is used to modify the existed customer
49 | - App.js uses React Router to navigate between components.
50 |
51 | ## Integrative Project Goal
52 |
53 | 
54 |
55 |
56 | Tutorial Link: [SpringBoot + React + PostgreSQL](https://loizenai.com/reactjs-springboot-crud-postgresql/)
57 |
58 | Reactjs + SpringBoot serial:
59 |
60 | Reactjs SpringBoot serial tutorials:
61 | - [How to Integrate Reactjs with SpringBoot Tutorial](https://loizenai.com/integrate-reactjs-springboot/)
62 | - [SpringBoot + React + MySQL: SpringBoot React.js CRUD Example](https://loizenai.com/springboot-react-mysql-crud-example/)
63 | - [SpringBoot + React + PostgreSQL: SpringBoot React.js CRUD Example](https://loizenai.com/reactjs-springboot-crud-postgresql/)
64 |
65 | Related posts:
66 |
67 | - [Angular 10 + Nodejs JWT Token Based Authentication with MongoDB Example – Express RestAPIs + JWT + BCryptjs + Sequelize](https://loizenai.com/angular-10-nodejs-jwt-authentication-MongoDB-examples-tutorials/)
68 | - [SpringBoot + Angular 9 + PostgreSQL CRUD Example – Architecture Diagram](https://loizenai.com/springboot-angular-9-postgresql-crud-example-architecture-diagram/)
69 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.4.RELEASE
9 |
10 |
11 | com.loizenai.springboot
12 | SpringBootCrudReact
13 | 1.00
14 | SpringBootCrudReact
15 | SpringBoot CRUD RestAPI with React.js Client
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-web
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | 1.18.10
34 | provided
35 |
36 |
37 | org.postgresql
38 | postgresql
39 | runtime
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 | org.junit.vintage
48 | junit-vintage-engine
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.springframework.boot
58 | spring-boot-maven-plugin
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/main/java/com/loizenai/springboot/reactjs/Initializer.java:
--------------------------------------------------------------------------------
1 | package com.loizenai.springboot.reactjs;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 |
6 | import org.springframework.boot.CommandLineRunner;
7 | import org.springframework.stereotype.Component;
8 |
9 | import com.loizenai.springboot.reactjs.model.Customer;
10 | import com.loizenai.springboot.reactjs.repository.CustomerRepository;
11 |
12 | @Component
13 | class Initializer implements CommandLineRunner {
14 |
15 | private final CustomerRepository repository;
16 |
17 | public Initializer(CustomerRepository repository) {
18 | this.repository = repository;
19 | }
20 |
21 | @Override
22 | public void run(String... strings) {
23 |
24 | ArrayList customers = new ArrayList( Arrays.asList(
25 | new Customer("Jack", "Smith", "374 William S Canning Blvd", 23),
26 | new Customer("Adam", "Johnson", "Fall River MA 2721. 121 Worcester Rd", 31),
27 | new Customer("Dana", "Bay", "Framingham MA 1701. 677 Timpany Blvd", 46)) );
28 |
29 | System.out.println(customers);
30 |
31 | repository.saveAll(customers);
32 |
33 | repository.findAll().forEach(System.out::println);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/java/com/loizenai/springboot/reactjs/SpringBootCrudReactApplication.java:
--------------------------------------------------------------------------------
1 | package com.loizenai.springboot.reactjs;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class SpringBootCrudReactApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(SpringBootCrudReactApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/loizenai/springboot/reactjs/controller/CustomerController.java:
--------------------------------------------------------------------------------
1 | package com.loizenai.springboot.reactjs.controller;
2 |
3 | import java.net.URI;
4 | import java.net.URISyntaxException;
5 | import java.util.Collection;
6 | import java.util.Optional;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.http.HttpStatus;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.web.bind.annotation.DeleteMapping;
13 | import org.springframework.web.bind.annotation.GetMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.PostMapping;
16 | import org.springframework.web.bind.annotation.PutMapping;
17 | import org.springframework.web.bind.annotation.RequestBody;
18 | import org.springframework.web.bind.annotation.RequestMapping;
19 | import org.springframework.web.bind.annotation.RestController;
20 |
21 | import com.loizenai.springboot.reactjs.model.Customer;
22 | import com.loizenai.springboot.reactjs.repository.CustomerRepository;
23 |
24 | @RestController
25 | @RequestMapping("/api")
26 | public class CustomerController {
27 |
28 |
29 | private final Logger log = LoggerFactory.getLogger(CustomerController.class);
30 | private CustomerRepository customerRepository;
31 |
32 | public CustomerController(CustomerRepository customerRepository) {
33 | this.customerRepository = customerRepository;
34 | }
35 |
36 | @GetMapping("/customers")
37 | Collection customers() {
38 | return customerRepository.findAll();
39 | }
40 |
41 | @GetMapping("/customer/{id}")
42 | ResponseEntity> getCustomer(@PathVariable Long id) {
43 | Optional customer = customerRepository.findById(id);
44 | return customer.map(response -> ResponseEntity.ok().body(response))
45 | .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
46 | }
47 |
48 | @PostMapping("/customer")
49 | ResponseEntity createCustomer(@RequestBody Customer customer) throws URISyntaxException {
50 | log.info("Request to create customer: {}", customer);
51 | Customer result = customerRepository.save(customer);
52 | return ResponseEntity.created(new URI("/api/group/" + result.getId()))
53 | .body(result);
54 | }
55 |
56 | @PutMapping("/customer")
57 | ResponseEntity updateGroup(@RequestBody Customer customer) {
58 | log.info("Request to update customer: {}", customer);
59 | Customer result = customerRepository.save(customer);
60 | return ResponseEntity.ok().body(result);
61 | }
62 |
63 | @DeleteMapping("/customer/{id}")
64 | public ResponseEntity> deleteCustomer(@PathVariable Long id) {
65 | log.info("Request to delete customer: {}", id);
66 | customerRepository.deleteById(id);
67 | return ResponseEntity.ok().build();
68 | }
69 | }
--------------------------------------------------------------------------------
/src/main/java/com/loizenai/springboot/reactjs/model/Customer.java:
--------------------------------------------------------------------------------
1 | package com.loizenai.springboot.reactjs.model;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 | import javax.persistence.Table;
7 |
8 | import lombok.Data;
9 | import lombok.NoArgsConstructor;
10 | import lombok.NonNull;
11 | import lombok.RequiredArgsConstructor;
12 |
13 | @Data
14 | @NoArgsConstructor
15 | @RequiredArgsConstructor
16 | @Entity
17 | @Table(name = "customer")
18 | public class Customer {
19 |
20 | @Id
21 | @GeneratedValue
22 | private Long id;
23 |
24 | @NonNull
25 | private String firstname;
26 | @NonNull
27 | private String lastname;
28 | private String address;
29 | private int age;
30 | private String copyright = "https://loizenai.com";
31 |
32 | public String toString() {
33 | return String.format("id=%d, firstname='%s', lastname'%s', address=%s, age=%d",
34 | id, firstname, lastname, address, age);
35 | }
36 |
37 | public Customer(String firstname, String lastname, String address, int age) {
38 | this.firstname = firstname;
39 | this.lastname = lastname;
40 | this.address = address;
41 | this.age = age;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/loizenai/springboot/reactjs/repository/CustomerRepository.java:
--------------------------------------------------------------------------------
1 | package com.loizenai.springboot.reactjs.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | import com.loizenai.springboot.reactjs.model.Customer;
6 |
7 | public interface CustomerRepository extends JpaRepository {
8 | Customer findByFirstname(String firstname);
9 | }
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.datasource.url=jdbc:mysql://localhost:3306/loizenaidb
2 | spring.datasource.username=root
3 | spring.datasource.password=12345
4 | spring.jpa.generate-ddl=true
5 |
6 | #drop & create table again, good for testing, comment this in production
7 | spring.jpa.hibernate.ddl-auto=create
--------------------------------------------------------------------------------
/src/test/java/com/loizenai/springboot/reactjs/SpringBootCrudReactApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.loizenai.springboot.reactjs;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class SpringBootCrudReactApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------