Likes & Reactions System
Relevant source files
The following files were used as context for generating this wiki page:
- src/main/java/org/example/coding_convention/likes/controller/LikeController.java
- src/main/java/org/example/coding_convention/likes/service/LikeService.java
- src/main/java/org/example/coding_convention/likes/model/Like.java
- src/main/java/org/example/coding_convention/likes/repository/LikeRepository.java
- src/main/java/org/example/coding_convention/project/model/Project.java
- src/main/java/org/example/coding_convention/project/model/ProjectDto.java
- src/main/resources/data.sql
The Likes & Reactions System in PhanesEditor-BE provides a mechanism for users to express interest in specific coding projects. It functions as a "toggle" system where a user can either add or remove a like from a project with a single action. This system is integrated with the project search and discovery features, allowing users to see the popularity of projects through a de-normalized like count.
The system is built using Spring Boot, Spring Data JPA, and MariaDB. It ensures data integrity through transactional operations that synchronize the individual Like records with the aggregate like_count stored on the Project entity.
Sources: src/main/java/org/example/coding_convention/likes/service/LikeService.java, src/main/java/org/example/coding_convention/project/model/Project.java:58-72
System Architecture and Logic
The system follows a standard Controller-Service-Repository pattern. The core logic resides in the LikeService, which determines whether to create or delete a Like record based on the current state of the database.
Logic Flow: Toggle Mechanism
When a user requests to "like" a project, the system performs the following steps:
- Identifies the
Userfrom the authentication principal. - Retrieves the target
Projectby its index. - Checks if a
Likerecord already exists for that specific User-Project pair. - If exists: Deletes the
Likerecord and decrements theProject.like_count. - If not exists: Creates a new
Likerecord and increments theProject.like_count.
The diagram shows the decision logic for the toggle mechanism within a single transactional unit.
Sources: src/main/java/org/example/coding_convention/likes/service/LikeService.java:18-34
Data Model and Schema
The system utilizes a dedicated likes table to manage many-to-many relationships between users and projects, while maintaining a de-normalized count in the project table for performance during searches.
Entity Relationships
The Like entity serves as a join table linking User and Project. Each Like record is unique to a specific user and project.
The ER diagram illustrates the relationship between users, projects, and the likes that connect them.
Sources: src/main/java/org/example/coding_convention/likes/model/Like.java, src/main/resources/data.sql:72-78
Database Schema Details
| Table | Column | Type | Constraints | Description |
|---|---|---|---|---|
likes | idx | INT | PRIMARY KEY, AUTO_INCREMENT | Unique identifier for the like record. |
likes | user_idx | INT | FOREIGN KEY (users.idx) | Reference to the user who liked the project. |
likes | project_idx | INT | FOREIGN KEY (project.idx) | Reference to the project being liked. |
project | like_count | INT | DEFAULT 0, NOT NULL | De-normalized counter for total likes. |
Sources: src/main/resources/data.sql:57-78, src/main/java/org/example/coding_convention/project/model/Project.java:58-60
API Implementation
The system exposes a single endpoint to handle the toggling of likes.
Endpoint Specification
- URL:
/like/{idx} - Method:
GET - Authentication: Requires a JWT (Bearer Auth).
- Path Variable:
idx(Integer) - The unique identifier of the project.
@GetMapping("/{idx}")
public BaseResponse likes(@AuthenticationPrincipal UserDto.AuthUser authUser, @PathVariable Integer idx) {
likeService.likes(authUser, idx);
return BaseResponse.success("완료");
}
Sources: src/main/java/org/example/coding_convention/likes/controller/LikeController.java:18-23
Response Structure
The system uses a BaseResponse wrapper for all operations.
| Field | Type | Description |
|---|---|---|
success | Boolean | Indicates if the toggle operation was successful. |
message | String | Returns "완료" (Completed) upon success. |
results | Object | Null for this operation. |
Sources: src/main/java/org/example/coding_convention/common/model/BaseResponse.java, src/main/java/org/example/coding_convention/likes/controller/LikeController.java:21
Integration with Project Search
The like_count is a critical field in the ProjectSearchRes DTO, which is used when users search for or list projects.
Search Result DTO
The ProjectDto.ProjectSearchRes includes the likeCount to provide immediate feedback on project popularity without requiring additional joins or count queries during list rendering.
public static ProjectDto.ProjectSearchRes from(Project entity) {
return ProjectSearchRes.builder()
.idx(entity.getIdx())
.name(entity.getProjectName())
.creator(entity.getUser().getNickname())
.language(entity.getLanguage().toString())
.description(entity.getDescription())
.likeCount(entity.getLikeCount()) // Integrated like count
.build();
}
Sources: src/main/java/org/example/coding_convention/project/model/ProjectDto.java:125-136
Summary
The Likes & Reactions System provides a streamlined, transactional way for users to interact with projects. By combining a relational Like record for tracking specific user actions with a de-normalized like_count on the Project entity, the system achieves both data integrity and high-performance read access for project discovery.