List Categories Endpoint Part 1

Building upon our entities and repositories from previous lessons, we'll create our first API endpoint that lists blog categories.

We'll implement this functionality layer by layer, starting with the controller and working through to the service implementation.

This endpoint will serve as a foundation for category management and content organization in our blog platform.

Creating the Controller Package

The controllers package will house all our REST API endpoints.

Let's create the package structure:

src/main/java/com/devtiro/blog/controllers/

Implementing the Category Controller

The CategoryController will handle all category-related HTTP requests.

package com.devtiro.blog.controllers; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/api/v1/categories") @RequiredArgsConstructor public class CategoryController { private final CategoryService categoryService; @GetMapping public ResponseEntity<List<CategoryDto>> listCategories() { // TODO } }

Creating the DTOs Package

DTOs (Data Transfer Objects) separate our API representation from internal domain models.

Let's create the package:

src/main/java/com/devtiro/blog/domain/dtos/

Implementing Category DTO

The CategoryDto represents the category data that will be sent to clients.

package com.devtiro.blog.domain.dtos; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.UUID; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class CategoryDto { private UUID id; private String name; private long postCount; }

Creating the Services Package

The services package will contain our business logic interfaces and implementations.

Let's create the package:

src/main/java/com/devtiro/blog/services/

Defining the Category Service Interface

The CategoryService interface defines the contract for category-related operations.

package com.devtiro.blog.services; import com.devtiro.blog.domain.entities.Category; import java.util.List; public interface CategoryService { /** * Lists all categories with their post counts. */ List<Category> listCategories(); }

Implementing the Category Service

The CategoryServiceImpl provides the concrete implementation of our service interface.

package com.devtiro.blog.services.impl; import com.devtiro.blog.domain.entities.Category; import com.devtiro.blog.repositories.CategoryRepository; import com.devtiro.blog.services.CategoryService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @RequiredArgsConstructor @Transactional(readOnly = true) public class CategoryServiceImpl implements CategoryService { private final CategoryRepository categoryRepository; @Override public List<Category> listCategories() { return categoryRepository.findAllWithPostCount(); } }

Extending the Category Repository

We need to add a method to fetch categories with their post counts.

Update the CategoryRepository interface:

package com.devtiro.blog.repositories; import com.devtiro.blog.domain.entities.Category; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; import java.util.UUID; @Repository public interface CategoryRepository extends JpaRepository<Category, UUID> { @Query("SELECT c FROM Category c LEFT JOIN FETCH c.posts") List<Category> findAllWithPostCount(); }

Now we can get a list of Category objects, but how do we convert them into CategoryDto objects? Let's cover that in the next lesson.

Summary

  • Created necessary package structure for controllers, DTOs, and services
  • Implemented CategoryController with initial listCategories endpoint
  • Created CategoryDto for API response representation
  • Defined CategoryService interface with listCategories method
  • Implemented CategoryServiceImpl with repository integration
© 2026 Devtiro Ltd. All rights reserved