Spring BootJavaREST APITutorialBeginners
Spring Boot REST API Tutorial for Beginners — Build Your First API in 30 Minutes
Siva Prasad Galaba· Staff Engineer & Founder, CodeBegun·
Step-by-step tutorial to build a Spring Boot REST API from scratch. Covers project setup, controllers, JPA, MySQL, and testing with Postman. Perfect for Java beginners.
## Build Your First Spring Boot REST API
This tutorial walks you through building a complete Student Management REST API using Spring Boot, Spring Data JPA, and MySQL — from zero to working API in 30 minutes.
**What you will build:** A REST API with full CRUD operations for managing students. You will be able to create, read, update, and delete student records using Postman.
**Prerequisites:** Java 17+ installed, IntelliJ IDEA (Community Edition is fine), MySQL installed and running.
## Step 1 — Create the Project
Go to [start.spring.io](https://start.spring.io) and configure:
- **Project**: Maven
- **Language**: Java
- **Spring Boot**: 3.3.x
- **Group**: com.codebegun
- **Artifact**: student-api
- **Packaging**: Jar
- **Java**: 21
Add these **Dependencies**:
- Spring Web
- Spring Data JPA
- MySQL Driver
- Lombok
- Spring Boot DevTools
Click **Generate**, unzip the file, and open it in IntelliJ IDEA.
## Step 2 — Configure the Database
Open `src/main/resources/application.properties` and add:
```properties
spring.datasource.url=jdbc:mysql://localhost:3306/studentdb?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=your_password_here
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
```
Replace `your_password_here` with your MySQL root password. Spring Boot will create the `studentdb` database automatically on first run.
## Step 3 — Create the Student Entity
Create a new file: `src/main/java/com/codebegun/studentapi/entity/Student.java`
```java
package com.codebegun.studentapi.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "students")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String email;
private String course;
private String city;
}
```
**What just happened:**
- `@Entity` tells JPA this class maps to a database table
- `@Table(name = "students")` sets the table name
- `@Id` and `@GeneratedValue` configure the primary key with auto-increment
- `@Column(nullable = false)` enforces NOT NULL at the database level
- Lombok's `@Data` generates getters, setters, equals, hashCode, and toString automatically
## Step 4 — Create the Repository
Create: `src/main/java/com/codebegun/studentapi/repository/StudentRepository.java`
```java
package com.codebegun.studentapi.repository;
import com.codebegun.studentapi.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
Optional<Student> findByEmail(String email);
List<Student> findByCityIgnoreCase(String city);
}
```
`JpaRepository<Student, Long>` gives you `save()`, `findById()`, `findAll()`, `delete()`, and more — with zero implementation code.
## Step 5 — Create the Service
Create: `src/main/java/com/codebegun/studentapi/service/StudentService.java`
```java
package com.codebegun.studentapi.service;
import com.codebegun.studentapi.entity.Student;
import com.codebegun.studentapi.repository.StudentRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class StudentService {
private final StudentRepository repo;
public List<Student> getAll() {
return repo.findAll();
}
public Student getById(Long id) {
return repo.findById(id)
.orElseThrow(() -> new RuntimeException("Student not found with id: " + id));
}
public Student create(Student student) {
return repo.save(student);
}
public Student update(Long id, Student updated) {
Student existing = getById(id);
existing.setName(updated.getName());
existing.setEmail(updated.getEmail());
existing.setCourse(updated.getCourse());
existing.setCity(updated.getCity());
return repo.save(existing);
}
public void delete(Long id) {
repo.deleteById(id);
}
}
```
## Step 6 — Create the REST Controller
Create: `src/main/java/com/codebegun/studentapi/controller/StudentController.java`
```java
package com.codebegun.studentapi.controller;
import com.codebegun.studentapi.entity.Student;
import com.codebegun.studentapi.service.StudentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/students")
@RequiredArgsConstructor
public class StudentController {
private final StudentService service;
@GetMapping
public ResponseEntity<List<Student>> getAll() {
return ResponseEntity.ok(service.getAll());
}
@GetMapping("/{id}")
public ResponseEntity<Student> getById(@PathVariable Long id) {
return ResponseEntity.ok(service.getById(id));
}
@PostMapping
public ResponseEntity<Student> create(@RequestBody Student student) {
return ResponseEntity.status(HttpStatus.CREATED).body(service.create(student));
}
@PutMapping("/{id}")
public ResponseEntity<Student> update(@PathVariable Long id, @RequestBody Student student) {
return ResponseEntity.ok(service.update(id, student));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
service.delete(id);
return ResponseEntity.noContent().build();
}
}
```
**The annotations explained:**
- `@RestController` — combines `@Controller` + `@ResponseBody`; all methods return JSON
- `@RequestMapping("/api/students")` — base path for all endpoints in this controller
- `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping` — HTTP method bindings
- `@PathVariable` — extracts `{id}` from the URL
- `@RequestBody` — deserializes the JSON body into a `Student` object
## Step 7 — Run and Test
Run the application from IntelliJ (click the green Run button or `Shift + F10`). You should see:
```
Started StudentApiApplication in 3.2 seconds
```
Open **Postman** and test each endpoint:
### Create a Student (POST)
```
POST http://localhost:8080/api/students
Content-Type: application/json
{
"name": "Priya Reddy",
"email": "priya@example.com",
"course": "Java Full Stack",
"city": "Hyderabad"
}
```
### Get All Students (GET)
```
GET http://localhost:8080/api/students
```
### Get Student by ID (GET)
```
GET http://localhost:8080/api/students/1
```
### Update Student (PUT)
```
PUT http://localhost:8080/api/students/1
Content-Type: application/json
{
"name": "Priya Reddy",
"email": "priya@example.com",
"course": "Java Full Stack",
"city": "Hyderabad"
}
```
### Delete Student (DELETE)
```
DELETE http://localhost:8080/api/students/1
```
## What's Next
You have built a working Spring Boot REST API in 30 minutes. The natural next steps:
1. **Add validation** — use `@Valid` + `@NotBlank`, `@Email` annotations on the `Student` entity
2. **Add proper error handling** — use `@ControllerAdvice` to return structured error responses
3. **Add JWT authentication** — with Spring Security
4. **Write unit tests** — with JUnit 5 and Mockito
5. **Connect a React frontend** — build a UI that calls these endpoints
6. **Deploy to AWS** — package as a Docker container and deploy to EC2
---
Want to learn this in a structured program with daily mentorship and real projects? [Explore CodeBegun's Java Full Stack training](/java-full-stack) — or [WhatsApp us](https://wa.me/916301099587) to join the next batch.
Siva Prasad Galaba
Staff Engineer & Founder, CodeBegun
Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaching the next generation to code the way the industry actually works.
