Spring Boot REST API Tutorial for Beginners — Build Your First API in 30 Minutes
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 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:
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
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:
@Entitytells JPA this class maps to a database table@Table(name = "students")sets the table name@Idand@GeneratedValueconfigure the primary key with auto-increment@Column(nullable = false)enforces NOT NULL at the database level- Lombok's
@Datagenerates getters, setters, equals, hashCode, and toString automatically
Step 4 — Create the Repository
Create: src/main/java/com/codebegun/studentapi/repository/StudentRepository.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
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
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 aStudentobject
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:
- Add validation — use
@Valid+@NotBlank,@Emailannotations on theStudententity - Add proper error handling — use
@ControllerAdviceto return structured error responses - Add JWT authentication — with Spring Security
- Write unit tests — with JUnit 5 and Mockito
- Connect a React frontend — build a UI that calls these endpoints
- 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 — or WhatsApp us to join the next batch.
Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaching the next generation to code the way the industry actually works.
