Spring Boot REST API Tutorial: Step-by-Step Guide (2026)

How-To Guide — owndevz.com

Spring Boot REST API Tutorial: Build One from Scratch (2026)

Step-by-step guide for beginners — project setup, controllers, service layer, repository, and Postman testing.

☕ Java / Spring Boot⏱️ 15 min read🎯 Beginner to Intermediate

If you want to build real-world Java backend applications, Spring Boot is the most in-demand framework you can learn in 2026. This Spring Boot REST API tutorial walks you through everything from project setup to Postman testing — no prior Spring experience needed.

What Is a REST API?

A REST API (Representational State Transfer API) is a way for different applications to communicate over the internet using standard HTTP methods. Think of it as a waiter in a restaurant — your frontend places an order, the REST API carries it to the kitchen (database), and brings back the data.

GET
Fetch data
POST
Create data
PUT
Update data
DELETE
Delete data
PATCH
Partial update

Step 1 — Project Setup with Spring Initializr

Go to start.spring.io and set up your project with these settings:

  • Project: Maven
  • Language: Java 17+
  • Spring Boot: 3.2.x (latest stable)
  • Dependencies: Spring Web, Spring Data JPA, MySQL Driver, Lombok

Click Generate, download and open the project in IntelliJ IDEA or VS Code. Your folder structure will look like this:

Project Structureowndevz.com
src/main/java/com/owndevz/api/
├── controller/   ProductController.java
├── service/      ProductService.java
├── repository/   ProductRepository.java
├── model/        Product.java
└── ApiApplication.java

Step 2 — Configure Database (application.properties)

application.propertiesowndevz.com
server.port=8080

spring.datasource.url=jdbc:mysql://localhost:3306/owndevz_db
spring.datasource.username=root
spring.datasource.password=yourpassword

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
💡 Pro Tip
Use ddl-auto=create in development to auto-create tables. Switch to update or validate in production to avoid data loss.

Step 3 — Create the Model (Entity)

A Model maps directly to a database table. We will build a Product API — a classic real-world example. The @Data Lombok annotation auto-generates all getters, setters and constructors:

Product.javaowndevz.com
@Entity
@Table(name = "products")
@Data
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    private String description;
    private Double price;
    private Integer stock;
}

Step 4 — Create the Repository Layer

The Repository handles all database operations. Extending JpaRepository gives you full CRUD for free — no SQL needed:

ProductRepository.javaowndevz.com
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

    // Spring auto-generates SQL from the method name!
    List<Product> findByNameContainingIgnoreCase(String name);
    List<Product> findByPriceLessThan(Double price);
}
💡 Query Derivation
Spring Data JPA reads method names like findByNameContaining and automatically generates the correct SQL query. No @Query annotation needed for simple lookups.

Step 5 — Create the Service Layer

The Service layer holds all business logic. It sits between the Controller and Repository — keeping your code clean, testable and maintainable:

ProductService.javaowndevz.com
@Service
@RequiredArgsConstructor
public class ProductService {

    private final ProductRepository repo;

    public List<Product> getAllProducts() {
        return repo.findAll();
    }

    public Optional<Product> getProductById(Long id) {
        return repo.findById(id);
    }

    public Product createProduct(Product product) {
        return repo.save(product);
    }

    public Product updateProduct(Long id, Product updated) {
        return repo.findById(id).map(p -> {
            p.setName(updated.getName());
            p.setPrice(updated.getPrice());
            p.setStock(updated.getStock());
            return repo.save(p);
        }).orElseThrow(() -> new RuntimeException("Product not found: " + id));
    }

    public void deleteProduct(Long id) {
        repo.deleteById(id);
    }
}

Step 6 — Create the REST Controller

The Controller is the entry point of your API. It receives HTTP requests, delegates work to the Service, and returns proper HTTP responses:

ProductController.javaowndevz.com
@RestController
@RequestMapping("/api/v1/products")
@RequiredArgsConstructor
public class ProductController {

    private final ProductService service;

    @GetMapping
    public ResponseEntity<List<Product>> getAll() {
        return ResponseEntity.ok(service.getAllProducts());
    }

    @GetMapping("/{id}")
    public ResponseEntity<Product> getById(@PathVariable Long id) {
        return service.getProductById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<Product> create(@RequestBody Product product) {
        return ResponseEntity.status(201).body(service.createProduct(product));
    }

    @PutMapping("/{id}")
    public ResponseEntity<Product> update(@PathVariable Long id, @RequestBody Product p) {
        return ResponseEntity.ok(service.updateProduct(id, p));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable Long id) {
        service.deleteProduct(id);
        return ResponseEntity.noContent().build();
    }
}
💡 @RestController vs @Controller
Always use @RestController for REST APIs — it combines @Controller and @ResponseBody, automatically converting your Java objects to JSON responses.

Step 7 — Test with Postman

Run your app (mvn spring-boot:run or run ApiApplication.java) then test each endpoint in Postman:

MethodEndpointActionStatus
GET/api/v1/productsGet all200 OK
POST/api/v1/productsCreate new201 Created
PUT/api/v1/products/1Update200 OK
DELETE/api/v1/products/1Delete204 No Content

For POST, go to Body → raw → JSON in Postman and send:

POST Request Bodyowndevz.com
{
  "name": "MacBook Pro M3",
  "description": "16-inch Apple laptop",
  "price": 199999.00,
  "stock": 50
}

Common Mistakes to Avoid

⚠️ Common Mistake
Using @Controller instead of @RestController. @Controller alone tries to render a view template and will throw an error. Always use @RestController for REST APIs — it automatically serialises return values to JSON.
⚠️ Common Mistake
Returning 200 OK for everything. A created resource should return 201 Created. A missing resource should return 404 Not Found. A deletion should return 204 No Content. Use ResponseEntity to set the correct status code every time.
⚠️ Common Mistake
Putting business logic inside the Controller. Controllers should only handle HTTP routing. All calculations, validations, and data transformations belong in the Service layer. Mixing them makes your code hard to test and maintain.
⚠️ Common Mistake
Exposing your @Entity directly as the API response in production. Use a DTO (Data Transfer Object) instead. This prevents leaking sensitive fields and decouples your API contract from your database schema.

What to Build Next

  • Exception Handling — Add a global @ControllerAdvice for clean, consistent error responses
  • Input Validation — Use @Valid with @NotNull, @Size, @Min on request bodies
  • DTOs — Decouple your API from your database schema using Data Transfer Objects
  • Spring Security + JWT — Add authentication to protect your endpoints
  • Pagination — Use Spring Data JPA’s Pageable for large result sets
  • Swagger / OpenAPI — Auto-generate API docs using springdoc-openapi

Conclusion

You have just built a fully working Spring Boot REST API from scratch. You learned how to set up a project with Spring Initializr, structure your application into Controller, Service and Repository layers, create a JPA entity backed by MySQL, implement all CRUD operations, and test your API using Postman.

This layered architecture is the backbone of virtually every professional Java backend. Master it and you can build anything — from a simple product catalogue to a full enterprise microservice. Spring Boot’s convention-over-configuration approach means you spend more time on business logic and less time on setup and boilerplate.

Keep building, keep shipping. The best way to get better at Spring Boot is to build real projects with it.

🚀
Need help building your project?
Get expert guidance on Spring Boot, REST APIs, and full-stack development from the team at owndevz.
Contact us at owndevz →

Leave a comment

Verified by MonsterInsights