티스토리 뷰

티스토리 또는 velog를 보면 기본적으로 임시저장 기능이 있습니다.

그래서 이번에는 임시저장 기능을 구현해볼까 합니다.


요구사항

  • 1분마다 임시저장 요청이 들어간다.
  • 작성하고 있는 글의 제목이 없다면 임시저장불가 메시지를 띄운다.

생각해봐야 할 것

# 저장소를 DB를 사용할까? 저장소 클래스를 생성하여 사용할까?

임시저장은 말 그대로 중간에 저장하는 것입니다. 굳이 DB까지 갈 필요가 있을까란 생각을 했습니다.

하지만 저장소 클래스는 서버가 내려가는 순간 데이터가 삭제되기 때문에 임시저장기능의 의미가 없어집니다.

따라서 DB를 사용하기로 했습니다.

# 임시저장 테이블을 따로 만들어야할까?

게시글 임시저장 테이블을 만든다면 그냥 게시글 테이블과 속성이 거의 똑같습니다.(제목, 게시글, 썸네일, 카테고리 등등)

그래서 데이터의 중복이 발생하지 않을까라는 고민을 처음에는 했고 게시글 테이블에 임시저장 글임을 판별할 수 있는 컬럼을 둘까도 생각을 했습니다.

 

하지만 생각해보면 게시글과 임시저장 게시글의 제약조건이 다릅니다. 

예를 들어 일반 게시글의 경우 제목, 본문은 not null 이지만 임시저장 글의 경우 게시글은 null을 허용했습니다.

그래서 한 테이블에서 임시저장 글 판단 컬럼을 두어 판단하는 것은 힘들다고 생각되고 별도의 테이블을 생성하기로 결정했습니다.

 

또한 임시저장글 테이블은 별도의 연관관계를 맺지 않습니다. 임시저장만하고 진짜 게시글로 저장을 안할 수도 있기 때문입니다.


핵심기능

(핵심기능을 담고 있는 간단한 코드만 설명하겠습니다.)

1. 임시저장 및 갱신

처음 게시글을 작성하고 1분이 지나면 임시저장 요청이 들어가고 반환 값으로 해당 임시저장글의 PK가 반환됩니다.

(1분마다 요청은 자바스크립트의 setInterval()을 사용했습니다.)

@PostMapping
public Long saveTemporalBoard(@Valid @RequestBody TemporalBoardReq temporalBoardReq) {
    log.info("temporalBoardDto {}", temporalBoardReq.toString());
    return temporalBoardService.saveTemporalBoard(temporalBoardReq);
}

그리고 위 요청 이후에는 클라이언트가 임시저장 글의 PK를 알고있기에 해당 글에 대해 update 요청을 보냅니다.

@PostMapping("/{id}")
public String updateTemporalBoard(@Valid @RequestBody TemporalBoardReq temporalBoardReq,
                                  @PathVariable("id") Long id) {
    log.info("temporalBoardDto and Id {} {}", temporalBoardReq.toString(), id);

    try {
        temporalBoardService.updateTemporalBoard(temporalBoardReq, id);
        return "success";
    } catch (Exception e) {
        log.error("임시저장 중 오류 발생 {}", e.getMessage());
        return "error";
    }
}

2. 임시저장 이어 쓰기 및 삭제

임시저장을 했다면 이 글을 이어쓸 수도 있어야 합니다.

 

그래서 게시글 작성을 위해 에디터로 들어갈 때 임시저장한 글이 있다면 다시 쓸 것인지 사용자에게 물어보게 했습니다.

아래의 요청은 최신 임시저장글을 조회합니다.

TemporalBoard findTop1ByOrderByIdDesc();

(스프링 데이터 JPA의 쿼리메서드 기능을 활용했습니다.)

 

여기서 임시저장한 글을 이어쓰고 저장을 마쳤다면 임시저장 테이블에서는 해당 임시저장글을 삭제해야합니다.

그래서 임시저장한 글을 이어쓰고 등록버튼을 누르면 해당 글이 임시저장 테이블에서 삭제하도록 구현하였습니다.

httpRequest.onload = function () {
    if (httpRequest.status === 200) {
        removeTemporalBoard() // 임시저장 글 삭제
        alert("글이 등록되었습니다.");
        const boardId = httpRequest.response;
        window.location.href = "/board/" + boardId;
        
        .......

 

@DeleteMapping("/{id}")
public String deleteTemporalBoard(@PathVariable("id") Long id) {
    try {
        temporalBoardService.deleteTemporalBoard(id);
        return "success";
    } catch (Exception e) {
        log.error("임시저장 글 삭제 중 오류 발생 {}", e.getMessage());
        return "error";
    }
}

 

자세한 코드는 아래의 깃허브에서 보실 수 있습니다.

https://github.com/StartDeveloperKim/MyBlog/tree/main/blog/src/main/java/my/blog/temporalBoard

 

GitHub - StartDeveloperKim/MyBlog: 꾸준함이 목표인 사람의 블로그

꾸준함이 목표인 사람의 블로그. Contribute to StartDeveloperKim/MyBlog development by creating an account on GitHub.

github.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함