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
CategoryControllerwith initiallistCategoriesendpoint - Created
CategoryDtofor API response representation - Defined
CategoryServiceinterface withlistCategoriesmethod - Implemented
CategoryServiceImplwith repository integration