Skip to content

Commit 7ce0835

Browse files
authored
Merge pull request #24 from nettee-space/feature/driving-adapter
Driving Adapter 와 UseCase 구현
2 parents 0d26152 + 5ade3f8 commit 7ce0835

22 files changed

+783
-15
lines changed

build.gradle.kts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ repositories {
3636
dependencies {
3737
implementation("org.springframework.boot:spring-boot-starter-web")
3838
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
39+
implementation("org.springframework.boot:spring-boot-starter-validation")
3940

4041
// logging
4142
implementation("org.springframework.boot:spring-boot-starter-log4j2")
@@ -76,6 +77,8 @@ dependencies {
7677
testImplementation("io.kotest:kotest-runner-junit5:5.9.1")
7778
testImplementation("io.mockk:mockk:1.13.12")
7879
testImplementation(kotlin("script-runtime"))
80+
testCompileOnly("org.projectlombok:lombok") // 테스트 의존성 추가
81+
testAnnotationProcessor("org.projectlombok:lombok") // 테스트 의존성 추가
7982
testImplementation("io.kotest.extensions:kotest-extensions-spring:1.1.3")
8083
}
8184

@@ -100,8 +103,8 @@ tasks.withType<KotlinCompile> {
100103

101104
tasks.withType<JavaCompile> {
102105
options.compilerArgs.addAll(listOf(
103-
"--enable-preview"
104-
//"-Amapstruct.defaultComponentModel=spring",
106+
"--enable-preview",
107+
"-Amapstruct.defaultComponentModel=spring",
105108
))
106109
}
107110

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package me.nettee.board.adapter.driving.web;
2+
3+
import jakarta.validation.Valid;
4+
import lombok.RequiredArgsConstructor;
5+
import me.nettee.board.adapter.driving.web.dto.BoardCommandDto.BoardCommandResponse;
6+
import me.nettee.board.adapter.driving.web.dto.BoardCommandDto.BoardCreateCommand;
7+
import me.nettee.board.adapter.driving.web.dto.BoardCommandDto.BoardUpdateCommand;
8+
import me.nettee.board.adapter.driving.web.mapper.BoardDtoMapper;
9+
import me.nettee.board.application.usecase.BoardCreateUseCase;
10+
import me.nettee.board.application.usecase.BoardDeleteUseCase;
11+
import me.nettee.board.application.usecase.BoardUpdateUseCase;
12+
import org.springframework.http.HttpStatus;
13+
import org.springframework.web.bind.annotation.*;
14+
15+
@RestController
16+
@RequestMapping("/api/v1/boards")
17+
@RequiredArgsConstructor
18+
public class BoardCommandApi {
19+
20+
private final BoardCreateUseCase boardCreateUseCase;
21+
private final BoardUpdateUseCase boardUpdateUseCase;
22+
private final BoardDeleteUseCase boardDeleteUseCase;
23+
private final BoardDtoMapper boardDtoMapper;
24+
25+
@PostMapping
26+
@ResponseStatus(HttpStatus.CREATED)
27+
public BoardCommandResponse createBoard(@RequestBody @Valid BoardCreateCommand boardCreateCommand) {
28+
// Map to Domain
29+
var board = boardDtoMapper.toDomain(boardCreateCommand);
30+
31+
return BoardCommandResponse.builder()
32+
.board(boardCreateUseCase.createBoard(board))
33+
.build();
34+
}
35+
36+
@PatchMapping("/{id}")
37+
@ResponseStatus(HttpStatus.OK)
38+
public BoardCommandResponse updateBoard(@PathVariable("id") Long id,
39+
@Valid @RequestBody BoardUpdateCommand boardUpdateCommand) {
40+
// Map to Domain
41+
var board = boardDtoMapper.toDomain(id, boardUpdateCommand);
42+
43+
return BoardCommandResponse.builder()
44+
.board(boardUpdateUseCase.updateBoard(board))
45+
.build();
46+
}
47+
48+
@DeleteMapping("/{id}")
49+
@ResponseStatus(HttpStatus.NO_CONTENT)
50+
public void deleteBoard(@PathVariable("id") Long id) {
51+
boardDeleteUseCase.deleteBoard(id);
52+
}
53+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package me.nettee.board.adapter.driving.web;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import me.nettee.board.adapter.driving.web.dto.BoardQueryDto.BoardDetailResponse;
5+
import me.nettee.board.adapter.driving.web.mapper.BoardDtoMapper;
6+
import me.nettee.board.application.domain.type.BoardStatus;
7+
import me.nettee.board.application.model.BoardReadSummaryModel;
8+
import me.nettee.board.application.usecase.BoardReadByStatusesUseCase;
9+
import me.nettee.board.application.usecase.BoardReadUseCase;
10+
import org.springframework.data.domain.Page;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.web.bind.annotation.GetMapping;
13+
import org.springframework.web.bind.annotation.PathVariable;
14+
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.bind.annotation.RequestParam;
16+
import org.springframework.web.bind.annotation.RestController;
17+
import java.util.Set;
18+
19+
@RestController
20+
@RequestMapping("/api/v1/boards")
21+
@RequiredArgsConstructor
22+
public class BoardQueryApi {
23+
private final BoardReadUseCase boardReadUseCase;
24+
private final BoardReadByStatusesUseCase boardReadByStatusesUseCase;
25+
26+
private final BoardDtoMapper boardDtoMapper;
27+
28+
@GetMapping("/{boardId}")
29+
public BoardDetailResponse getBoard(@PathVariable("boardId") long boardId) {
30+
var board = boardReadUseCase.getBoard(boardId);
31+
32+
return boardDtoMapper.toDtoDetail(board);
33+
}
34+
35+
@GetMapping
36+
public Page<BoardReadSummaryModel> getBoardsByStatuses(@RequestParam Set<BoardStatus> statuses, Pageable pageable) {
37+
return boardReadByStatusesUseCase.findByStatuses(statuses, pageable);
38+
}
39+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package me.nettee.board.adapter.driving.web.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonRootName;
4+
import jakarta.validation.constraints.NotBlank;
5+
import jakarta.validation.constraints.Size;
6+
import lombok.Builder;
7+
import me.nettee.board.application.domain.Board;
8+
9+
public final class BoardCommandDto {
10+
11+
private BoardCommandDto() {
12+
}
13+
14+
public record BoardCreateCommand(
15+
@NotBlank(message = "제목을 입력하십시오.")
16+
@Size(min = 3, message = "제목은 세 글자 이상 입력하세요.")
17+
String title,
18+
@NotBlank(message = "본문을 입력하십시오")
19+
@Size(min = 3, message = "제목은 세 글자 이상 입력하세요.")
20+
String content
21+
) {
22+
}
23+
24+
public record BoardUpdateCommand(
25+
@NotBlank(message = "제목을 입력하십시오.")
26+
@Size(min = 3, message = "제목은 세 글자 이상 입력하세요.")
27+
String title,
28+
@NotBlank(message = "본문을 입력하십시오")
29+
@Size(min = 3, message = "제목은 세 글자 이상 입력하세요.")
30+
String content
31+
) {
32+
}
33+
34+
@Builder
35+
@JsonRootName("board")
36+
public record BoardCommandResponse(
37+
Board board
38+
) {
39+
}
40+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package me.nettee.board.adapter.driving.web.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonRootName;
4+
import lombok.Builder;
5+
import me.nettee.board.application.domain.type.BoardStatus;
6+
import me.nettee.board.application.model.BoardReadDetailModel;
7+
import me.nettee.board.application.model.BoardReadSummaryModel;
8+
9+
import java.time.Instant;
10+
11+
public final class BoardQueryDto {
12+
private BoardQueryDto() {}
13+
14+
@Builder
15+
public record BoardDetailResponse(
16+
BoardReadDetailModel board
17+
){}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package me.nettee.board.adapter.driving.web.mapper;
2+
3+
import me.nettee.board.adapter.driving.web.dto.BoardCommandDto.BoardCreateCommand;
4+
import me.nettee.board.adapter.driving.web.dto.BoardCommandDto.BoardUpdateCommand;
5+
import me.nettee.board.adapter.driving.web.dto.BoardQueryDto.BoardDetailResponse;
6+
import me.nettee.board.application.domain.Board;
7+
import me.nettee.board.application.model.BoardReadDetailModel;
8+
import org.mapstruct.Mapper;
9+
10+
@Mapper(componentModel = "spring")
11+
public interface BoardDtoMapper {
12+
13+
Board toDomain(BoardCreateCommand command);
14+
15+
Board toDomain(Long id, BoardUpdateCommand command);
16+
17+
BoardDetailResponse toDtoDetail(BoardReadDetailModel board);
18+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package me.nettee.board.application.model;
2+
3+
import java.time.Instant;
4+
import me.nettee.board.application.domain.type.BoardStatus;
5+
6+
public record BoardReadDetailModel(
7+
Long id,
8+
String title,
9+
String content,
10+
BoardStatus status,
11+
Instant createdAt,
12+
Instant updatedAt,
13+
Instant deletedAt
14+
) {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package me.nettee.board.application.model;
2+
3+
import java.time.Instant;
4+
5+
public record BoardReadSummaryModel(
6+
Long id,
7+
String title,
8+
String content,
9+
Instant createdAt,
10+
Instant updatedAt
11+
){}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package me.nettee.board.application.port;
22

3+
import java.util.Optional;
34
import me.nettee.board.application.domain.Board;
45

56
public interface BoardCommandPort {
67

8+
Optional<Board> findById(Long id);
9+
710
Board create(Board board);
811

912
Board update(Board board);
1013

11-
void delete(Long id);
12-
14+
void delete(Board id);
1315
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package me.nettee.board.application.port;
22

3-
import me.nettee.board.application.domain.Board;
3+
import java.util.Optional;
4+
import java.util.Set;
5+
import me.nettee.board.application.domain.type.BoardStatus;
6+
import me.nettee.board.application.model.BoardReadDetailModel;
7+
import me.nettee.board.application.model.BoardReadSummaryModel;
48
import org.springframework.data.domain.Page;
59
import org.springframework.data.domain.Pageable;
610

7-
import java.util.Optional;
8-
911
public interface BoardQueryPort {
1012

11-
Page<Board> findAll(Pageable pageable);
13+
Optional<BoardReadDetailModel> findById(Long id);
1214

13-
Optional<Board> findById(Long id);
15+
Page<BoardReadSummaryModel> findByStatusesList(Pageable pageable, Set<BoardStatus> statuses);
1416

1517
}

0 commit comments

Comments
 (0)