Get started with Fullstack Development: React + SpringBoot + MySQL + Postman
Tags: fullstack, react, springboot, beginners
Published: 2024-06-23 12:54:21

## Prerequisite:

- Basic knowledge of Javascript and React library
- Basic knowledge of Java, SpringBoot
- Basic knowledge of MySQL

## Architecture:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85qr9fp4vuy8jtqi94up.png)



## Tools and installation links:
- [Java openjdk 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
- [MySQL](https://dev.mysql.com/downloads/mysql/) and [MySQL Workbench](https://dev.mysql.com/downloads/workbench/)
- [Postman](https://www.postman.com/downloads/)
- [NodeJs](https://nodejs.org/en/download/package-manager/current), [yarn](https://tecadmin.net/install-yarn-macos/)
- IDE: [Intellij](https://www.jetbrains.com/idea/download/?section=mac)(for Backend), [VSCode](https://code.visualstudio.com/download)(for Frontend)

## Step 1: Spring Initializer
Spring Initializer is a web-based tool provided by the Spring framework that simplifies the process of creating a new Spring Boot project. It allows developers to quickly bootstrap a new Spring Boot application with the necessary dependencies and configurations.

To set up SpringBoot development environment - https://start.spring.io/

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pkd58hun77b5ap12l43.png)


Now open the extracted zip file in Intellij

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta99ma0swxe9sr1ym5a7.png)


## Step 2: Create packages in src main java
- model, repository, controller, exception 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smm8kekossij9zv8mqxf.png)

- The `model` represents the data of your application. In a Spring Boot application, models are typically Java classes annotated with JPA annotations that map the class properties to database columns.
- `Repositories` are responsible for interacting with the database. In Spring Boot, repositories are interfaces that extend JpaRepository or CrudRepository. Spring Data JPA provides the implementation at runtime.
- `Controllers` handle HTTP requests and responses. They are responsible for processing user inputs, invoking business logic, and returning the results. Controllers are typically annotated with @RestController.
- `Exception` handling handles exceptions globally and provide custom error responses.


## Step 3: Creating model class and connecting with MySql

`Model/User:`

```java
package com.demo.fullstack_backend.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue
    private long id;
    private String username;
    private String name;
    private String email;

    public long getId() {
        return id;
    }

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

    // other getters and setters (use @GeneratedValue)
}
```

<u>Annotations used:</u>
@Entity: help us to map our domain objects (POJOs) to the relational database tables
@id: to designate that this member will uniquely identify the entity in the database
@GeneratedValue: On right click -> Generate getters and setters


`repository/UserRepository`

```java
package com.demo.fullstack_backend.repository;

import com.demo.fullstack_backend.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> { // Long id will be used as primary key
}
```

Interface JpaRepository<T,ID> : Returns a reference to the entity with the given identifier. It contains the APIs for basic CRUD operations, the APIS for pagination, and the APIs for sorting.

## Step 4: Set MySQL configurations

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aksje9lkjgu7sii4288y.png)

**MySQL installation:**
- Download [MySQL server](https://dev.mysql.com/downloads/mysql/)
- Install the server
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p80v605nvk66zux08duo.png)
- Add bin path in bash profile: Open the terminal

1. If bash profile file is already present : `open ~/.bash_profile` else create and open the file
2. Add path: `export PATH=${PATH}:/usr/local/mysql-8.4.0-macos14-x86_64/bin`
3. `source ~/.bash_profile`
4. `mysql -u root -p`
5. Check if installation is successful: `show databases`

## Step 5: MySQL workbench
`create database fullstack; 
show databases;
use fullstack;
show tables;
desc user;
`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8hj4ffqxqs9zjpu6zbg.png)


## Step 6: Postmapping for sending data in database and Getmapping for getting data from databases

`controller/UserController`

```java
package com.demo.fullstack_backend.controller;

import com.demo.fullstack_backend.model.User;
import com.demo.fullstack_backend.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@CrossOrigin("http://localhost:3000")
@RestController
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @PostMapping("/user")
    User newUser(@RequestBody User newUser) {
        return userRepository.save(newUser);
    }

    @GetMapping("/users")
    List<User> getAllUsers() {
        return userRepository.findAll();
    }

}
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gi79v8cc3y9kl6h0g21r.png)



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy701lcsprv78ke6qwmn.png)

@RestController: used for developing RESTful web services
@Autowired: allows Spring to automatically inject dependencies into the class, eliminating the need for manual configuration
@CrossOrigin: provides a way to overcome the same-origin policy applied by web browser

## Step 7: Develop frontend using React and connect to springboot

- Install [Node](https://nodejs.org/en)
- Install [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable)
- On Terminal run: `yarn global add create-react-app`
- Create and open project folder in VSCode/ any IDE and run: 
  `create-react-app app-name`
- yarn add axios (to add axios library to web application. It is a popular JavaScript library used for making HTTP requests from a web browser or Node. js)
- To use readymade material components:
  - yarn add @mui/material @emotion/react @emotion/styled
  - yarn add @mui/icons-material
- Add [React developer tool chrome extension](https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) to inspect the React component hierarchies
- Run the application:

**Backend:**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqxpkefph8912hgwevlc.png)

**Frontend:**
`yarn start`

_**Good to goooo!!!**_

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nz8lp2k7867ecary1c5c.png)


After submitting new user data:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9dkn5ghlsv4w70fx5tg.png)

**React files:** (Just 4 files ;))
`App.js`

```javascript
import React, { useState, useEffect } from "react";
import axios from "axios";
import UserForm from "./Form/UserForm";
import UserList from "./UserList/UserList";
import "./App.css";

const App = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    loadUsers();
  }, []);

  const loadUsers = async () => {
    const result = await axios.get("http://localhost:8080/users");
    setUsers(result.data);
  };

  const addUser = (user) => {
    setUsers([...users, user]);
  };

  return (
    <div className="App">
      <h1>Fullstack Frontend</h1>
      <UserForm addUser={addUser} />
      <UserList users={users} />
    </div>
  );
};

export default App;

```

`App.css`

```css
.App {
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  background-color: #f4f4f9;
  padding: 20px;
  max-width: 800px;
  margin: 0 auto;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}

.container {
  margin-top: 20px;
}

h1 {
  text-align: center;
  color: #333;
  margin-bottom: 20px;
}

form {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}

form div {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  color: #333;
  font-weight: bold;
}

input[type="text"],
input[type="email"] {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}

button {
  width: 100%;
  background-color: #007bff;
  color: #fff;
  border: none;
  padding: 10px;
  border-radius: 4px;
  font-size: 16px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

button:hover {
  background-color: #0056b3;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  background-color: #fff;
  margin-bottom: 10px;
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

li strong {
  display: block;
  color: #007bff;
}

li + li {
  margin-top: 10px;
}

li div {
  margin-bottom: 5px;
}

```

`UserForm.js`

```javascript
import React, { useState } from "react";
import axios from "axios";

const UserForm = ({ addUser }) => {
  const [user, setUser] = useState({ name: "", email: "" });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setUser({ ...user, [name]: value });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (user.name && user.email) {
      addUser(user);
      setUser({ name: "", email: "" });
      await axios.post("http://localhost:8080/user", user);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Name:</label>
        <input
          type="text"
          name="name"
          value={user.name}
          onChange={handleChange}
          placeholder="Enter your name"
        />
      </div>
      <div>
        <label>Email:</label>
        <input
          type="email"
          name="email"
          value={user.email}
          onChange={handleChange}
          placeholder="Enter your email"
        />
      </div>
      <button type="submit" disabled={!(user.name && user.email)}>
        Add User
      </button>
    </form>
  );
};

export default UserForm;

```

`UserList.js`

```javascript
import React from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
} from "@mui/material";

const UserList = ({ users }) => {
  return (
    <TableContainer component={Paper} sx={{ mt: 4 }}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>ID</TableCell>
            <TableCell>Name</TableCell>
            <TableCell>Email</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {users.map((user, index) => (
            <TableRow key={index}>
              <TableCell>{index + 1}</TableCell>
              <TableCell>{user.name}</TableCell>
              <TableCell>{user.email}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default UserList;

```

## Basic React concepts
React is a popular JavaScript library for building user interfaces, particularly single-page applications where you need a fast and interactive user experience. Here are some basic and important concepts in React:
- `Components`: Building blocks of a React application. They are self-contained and reusable pieces of UI. Types: Functional components, class components. Functional components are widely used nowadays.
- `JSX`: JSX stands for JavaScript XML. It allows you to write HTML in React.
- `Props`: Props (short for properties) are read-only attributes used to pass data from parent components to child components.
- `State`: State is an object that represents the dynamic parts of a component and can change over time. State is managed within the component and can be updated using the setState method.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8w5lx1w11lenbo8aj6z.jpeg)


- `Lifecycle Methods`: Lifecycle methods are special methods in class components that allow you to hook into different phases of a component's life (mounting, updating, and unmounting). Examples: componentDidMount, componentDidUpdate, componentWillUnmount, etc.
- `Hooks`: Hooks are functions that let you use state and other React features in functional components. Examples: useState, useEffect, useContext, etc.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmm3ytm6cdhgzpogdf2f.png)



- `Context`: Context provides a way to pass data through the component tree without having to pass props down manually at every level. Useful for global state like themes or user data.
- `Handling Events`: Event handling in React involves defining event handlers directly in JSX, using camelCase syntax for event names (e.g., onClick), and passing functions that specify what should happen when an event occurs, ensuring a seamless interaction between user actions and the component's state or behavior. Handling events in React is similar to handling events on DOM elements.
- `Rendering`: Rendering refers to the process of displaying UI elements on the screen. In React, rendering typically involves the render method, which returns a description of what you want to see on the screen in the form of a React element.
- `Conditional Rendering`: It is the process of displaying elements and components based on certain conditions. Use JavaScript operators like if, &&, and ? : to create elements representing the current state.
- `Lists`: In React, working with lists often involves creating a dynamic collection of elements based on data arrays. Using JavaScript methods like map, reduce, and filter allows you to manipulate and render these lists efficiently.
- `Keys`: Keys help React optimize the rendering of lists by identifying each element uniquely.
- `Real DOM`: The Real DOM (Document Object Model) is a programming interface provided by web browsers that allows scripts to dynamically access and update the content, structure, and style of a document. It represents the entire structure of a web page as a tree of objects, where each object represents part of the document.
- `Virtual DOM`: The Virtual DOM is a lightweight representation of the real DOM. React uses it to optimize rendering by making updates in a more efficient way. When state or props change, React creates a new virtual DOM tree, compares it with the previous one (a process called "reconciliation"), and only updates the changed parts in the real DOM.
- `Fragment`: Fragment allows you to group multiple elements without adding extra nodes to the DOM.

```javascript
function FragmentExample() {
  return (
    <>
      <h1>Title</h1>
      <p>Description</p>
    </>
  );
}
```


## Bonus Info (Error and resolution):
1. If mysql server is automatically getting turned on/off: 
Go to System preferences/settings -> MySql =>
Regardless of version, **invalidate the caches**:
    a. Click File 🡒 Invalidate Caches / Restart.
    b. Click Invalidate and Restart.
2. Error: Can't connect to local MySQL server through socket '**/tmp/mysql.sock**' (2): issue resolved by https://www.landfx.com/kb/installation-help/mysql/3437-mysql-stop-mac


**Thanks for reading!**