As part of my Full Stack Development learning journey, I built a Student Marks Dashboard by integrating a React frontend with a Spring Boot backend. This project helped me understand how a modern web application communicates between the client side and server side using REST APIs.
The main goal of this project was to fetch student names and marks from the backend and display them dynamically in a table on the frontend. Even though the application is small, it covers several important concepts such as API creation, CORS handling, data fetching, state management, and dynamic rendering in React.
Technologies Used
- React.js
- Axios
- Spring Boot
- Java Collections (
Map,LinkedHashMap) - REST API
- HTML Table
- JavaScript ES6
- React Hooks (
useState,useEffect)
Backend Development with Spring Boot
For the backend, I created a Spring Boot REST controller that exposes a /students endpoint. This endpoint returns student names and marks in the form of a LinkedHashMap.
Using LinkedHashMap was useful because it preserves the insertion order of the data. That means the student records will appear in the same order in which they were added, which makes the output more predictable and easier to read.
@GetMapping("/students")
public Map<String,Integer> getStudents() {
Map<String,Integer> students = new LinkedHashMap<>();
students.put("Vidhya",99);
students.put("Arun",85);
students.put("Priya",92);
students.put("Karthik",78);
students.put("Divya",88);
students.put("Vijay",95);
students.put("Anu",81);
students.put("Rahul",89);
students.put("Meena",90);
students.put("Suresh",76);
students.put("Nisha",87);
return students;
}
The @RestController annotation plays an important role here. It tells Spring Boot that this class will handle REST requests and that the return value of the methods should be written directly into the HTTP response body. Since the method returns a Map<String, Integer>, Spring Boot automatically converts it into JSON format.
Sample JSON Response
When the /students endpoint is called, the backend sends the following JSON response:
{
"Vidhya": 99,
"Arun": 85,
"Priya": 92,
"Karthik": 78,
"Divya": 88,
"Vijay": 95,
"Anu": 81,
"Rahul": 89,
"Meena": 90,
"Suresh": 76,
"Nisha": 87
}
This JSON response is easy for the frontend to consume and display in a structured format.
Enabling Cross-Origin Requests
Since the React application runs on http://localhost:5173 and the Spring Boot application runs on http://localhost:8080, both applications are running on different ports. In browser-based applications, this creates a Cross-Origin Resource Sharing (CORS) issue because the frontend and backend are treated as different origins.
To solve this, I used the @CrossOrigin annotation in the controller:
@CrossOrigin(origins="http://localhost:5173")
This annotation allows requests from the React frontend to access the Spring Boot backend without being blocked by the browser. Without this configuration, the API call from React would fail due to CORS restrictions.
Frontend Development with React
On the frontend, I used React to build the user interface and Axios to fetch data from the backend API. React Hooks made the implementation clean and simple.
I used useState to store the student data and useEffect to make the API call when the component loads.
useEffect(() => {
axios("http://localhost:8080/students")
.then((response) => setStudents(response.data));
}, []);
Here, useEffect runs only once because the dependency array is empty ([]). This means the API request is triggered when the component is first rendered. Once the response is received, the data is stored in the students state using setStudents.
Initially, I declared the state as an empty object:
const [students, setStudents] = useState({});
This is because the backend returns an object in JSON format, and storing it as an object in React makes it easier to work with later.
Converting Object Data into Table Rows
Since the API response is an object and not an array, I used Object.entries() to convert the object into an array of key-value pairs. This is necessary because React can easily map over arrays to generate UI elements dynamically.
Object.entries(students).map(([name, mark]) => (
<tr key={name}>
<td>{name}</td>
<td>{mark}</td>
</tr>
))
This approach allows the table to render each student record dynamically without hardcoding any values. Every time the backend data changes, the frontend table will automatically reflect the updated values.
The complete table structure looks like this:
<table border="2">
<thead>
<tr>
<th>Name</th>
<th>Mark</th>
</tr>
</thead>
<tbody>
{Object.entries(students).map(([name, mark]) => (
<tr key={name}>
<td>{name}</td>
<td>{mark}</td>
</tr>
))}
</tbody>
</table>
This gives a clean and readable output in the browser.
What I Learned
This project helped me strengthen my understanding of full stack development and the interaction between frontend and backend technologies.
- Creating REST APIs using Spring Boot
- Returning structured data using
MapandLinkedHashMap - Using
@GetMappingto expose API endpoints - Handling CORS issues with
@CrossOrigin - Fetching backend data using Axios in React
- Managing component state with
useState - Triggering API calls with
useEffect - Converting JavaScript objects into arrays using
Object.entries() - Rendering dynamic data in React tables
- Understanding how JSON data flows from backend to frontend
Conclusion
This Student Marks Dashboard project gave me practical experience in building a full stack application from scratch. It showed me how a React frontend can communicate with a Spring Boot backend through REST APIs and how data can be transferred in JSON format and displayed dynamically in the UI.
Even though the project is simple, it covers many important concepts that are used in real-world applications. It also improved my confidence in working with React, Axios, Spring Boot, and API integration.
This kind of project is a great starting point for anyone learning full stack development because it connects theory with practical implementation.
Top comments (0)