[Spring] Simple Board - 구현

HOJUN·2024년 6월 15일

Backend - Spring

목록 보기
22/34

End Point

게시판의 CRUD를 위해 End Point를 개발해보자.
클라이언트가 서버와 통신하고자 하는 URL 경로로 해당 포스트에서는 CRUD 기능을 제공하기 위해 응답 요청을 구현하는 것으로 한다.

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class BoardRequest {

    @NotBlank
    private String boardName;
}

board 테이블에 추가할 것은 게시판 이름 뿐이므로 request는 boardName만 작성한다.

@Service
@RequiredArgsConstructor
public class BoardService {

    private final BoardRepository boardRepository;

    public BoardEntity create(
            BoardRequest boardRequest
    ) {
        var entity = BoardEntity.builder()
                .boardName(boardRequest.getBoardName())
                .status("REGISTERED").build();

        return boardRepository.save(entity);
    }
}

service에서 status를 REGISTERED 리터럴로 지정해준다. 그럼 ID는 Auto-Increament를 통해 자동으로 등록된다.

@RestController
@RequestMapping("/api/board")
@RequiredArgsConstructor
public class BoardController {

    private final BoardService boardService;

    @PostMapping("")
    public BoardEntity create(
            @Valid
            @RequestBody
            BoardRequest boardRequest
    ){
        return boardService.create(boardRequest);
    }
}

위와 같은 방법으로 post, reply도 작성할 수 있다.
단, column의 수가 더 많으므로 빠지지 않도록 유의하며 작성한다.

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class PostRequest {

    @NotBlank
    private String userName;

    @NotBlank
    @Size(min = 4, max = 4)
    private String password;

    @NotBlank
    @Email
    private String email;

    @NotBlank
    private String title;

    @NotBlank
    private String content;
}

단편적으로 post 테이블의 request 필드는 5개인데, 각각 NotNull을 달고 있으며 필드마다 조건을 달아줄 수 있다ㅏ.

public class PostEntity {

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

    private Long boardId;

    private String userName;

    private String password;

    private String email;

    private String status;

    private String title;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime postedAt;
}

post의 엔터티 필드인데, Service에서 엔터티를 만들 때 각 내용이 입력돼야한다.

QNA 게시판이라는 board를 생성한다.
위에서 boardEntity의 Status가 "REGISTERED"로 입력돼있기 때문에 자동으로 입력된다.

POST 요청을 하게되면 200 OK가 떨어진 것을 볼 수 있다.

데이터베이스에도 잘 적용이 됐다.
reply도 마찬가지로 동작한다.

public class ReplyEntity {

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

    private Long postId;

    private String userName;

    private String password;

    private String status;

    private String title;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime repliedAt;
}

post entity와 유사한 엔터티를 가지고 있고,

ublic class ReplyService {

    private final ReplyRepository replyRepository;
    private final PostRepository postRepository;

    public ReplyEntity create(
            ReplyRequest replyRequest
    ) {

        var optionalPostEntity = postRepository.findById(replyRequest.getPostId());

        if(optionalPostEntity.isEmpty()){
            throw new RuntimeException("게시물이 존재하지 않습니다. : " + replyRequest.getPostId());
        }
        var entity = ReplyEntity.builder()
                .post(optionalPostEntity.get())
                .userName(replyRequest.getUserName())
                .password(replyRequest.getPassword())
                .status("REGISTERED")
                .title(replyRequest.getTitle())
                .content(replyRequest.getContent())
                .repliedAt(LocalDateTime.now())
                .build();

        return replyRepository.save(entity);
    }

    public List<ReplyEntity> findAllByPostId(Long postId) {
        return replyRepository.findAllByPostIdAndStatusOrderByIdDesc(postId, "REGISTERED");
    }
}

같은 내용의 create 메소드이지만, 없을 수 있는 reply에 대한 처리는 optionalPostEntity로 처리한다.
물론 get으로 postId를 가져오는 것은 바람직하지는 않다.
위 내용을 적절하게 개선시킨 내용을 다음 포스팅에서 작성하도록 한다.

0개의 댓글