DEV Community

Cover image for Get started with Fullstack Development: React + SpringBoot + MySQL + Postman
Kajal Mapare
Kajal Mapare

Posted on • Updated on

Get started with Fullstack Development: React + SpringBoot + MySQL + Postman

Prerequisite:

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

Architecture:

Image description

Tools and installation links:

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

Now open the extracted zip file in Intellij

Image description

Step 2: Create packages in src main java

  • model, repository, controller, exception

Image description

  • 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:

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)
}
Enter fullscreen mode Exit fullscreen mode

Annotations used:
@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

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
}
Enter fullscreen mode Exit fullscreen mode

Interface JpaRepository : 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

MySQL installation:

  • Download MySQL server
  • Install the server Image description
  • 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

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

controller/UserController

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();
    }

}
Enter fullscreen mode Exit fullscreen mode

Image description

Image description

@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
  • Install yarn
  • 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 to inspect the React component hierarchies
  • Run the application:

Backend:

Image description

Frontend:
yarn start

Good to goooo!!!

Image description

After submitting new user data:

Image description

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

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;

Enter fullscreen mode Exit fullscreen mode

App.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;
}

Enter fullscreen mode Exit fullscreen mode

UserForm.js

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;

Enter fullscreen mode Exit fullscreen mode

UserList.js

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;

Enter fullscreen mode Exit fullscreen mode

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

  • 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

  • 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.
function FragmentExample() {
  return (
    <>
      <h1>Title</h1>
      <p>Description</p>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (4)

Collapse
 
chiragagg5k profile image
Chirag Aggarwal

Great post kajal! Since this was a beginner post I would have liked more in depth explanations next time. Keep it up!

Collapse
 
kajal_mapare24 profile image
Kajal Mapare

Sure Chirag !

Collapse
 
alekseiberezkin profile image
Aleksei Berezkin

Like right away for IntelliJ 😉

Collapse
 
yu_sun_0a160dea497156d354 profile image
Yu Sun • Edited

You can try using smart-doc to automatically generate postman collection, and then import it.

smart-doc-group.github.io/#/advanc...

Some comments may only be visible to logged-in visitors. Sign in to view all comments.