[클론 코딩] 네이버 카페 - 통합게시판 추가

2024. 5. 28. 17:47Project/Naver Cafe

  저번에는 카페 생성에 따라 기본 게시판이 추가되는 기능을 구현했으니, 이번에는 카페에 게시판을 추가하는 기능을 구현하고자 한다. 일단 네이버 카페에는 여러 타입의 게시판이 있지만 해당 게시글에서는 기본 타입인 '통합(일반) 게시판'에 대한 추가를 구현한다.

 

  사용자는 게시판 타입을 선택하면 게시판 추가를 위한 정보를 입력할 수 있는 양식을 응답 받는다. 그리고 양식에 정보를 입력해 서버에 전달하면 게시판이 추가될 것이다.


BulletinBoard

package CloneCoding.NaverCafe.domain.bulletinBoard;

import static CloneCoding.NaverCafe.domain.bulletinBoard.enums.BasicBulletinBoardData.*;
import static CloneCoding.NaverCafe.domain.cafeMember.enums.CafeMemberPosition.CAFE_MEMBER;

@Entity
@Table(name = "BULLETIN_BOARD")
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class BulletinBoard {

    public static BulletinBoard createGeneralBulletinBoard(Cafe cafe, RequestCreateGeneralBulletinBoard request) {
        return BulletinBoard.builder()
                .sequence(request.getSequence())
                .name(request.getName())
                .description(request.getDescription())
                .writeAuth(changeToPosition(request.getWriteAuth()))
                .readAuth(changeToPosition(request.getReadAuth()))
                .commentAuth(changeToPosition(request.getCommentAuth()))
                .useFavorite(request.isUseFavorite())
                .cafeId(cafe)
                .build();
    }

    private static String changeToPosition(String value) {
        CafeMemberPosition position = CafeMemberPosition.findByPosition(value);
        return position.name();
    }

}

 

  BulletinBoard 클래스에는 일반 게시판을 생성하는 메서드를 추가하였다.

  • createGeneralBulletinBoard() : 카페 정보와 요청 정보를 토대로 BulletinBoard 객체를 생성후 반환
  • changeToPosition() : 파라미터의 문자열과 매치되는 상수를 CafeMemberPosition에서 찾아 상수명을 반환
  • CafeMemberPosition.findByPosition() : 전달 정보로 CafeMemberPosition에서 정보와 일치하는 position 값을 가지는 상수를 찾아 반환

ResponseGeneralCreateForm

package CloneCoding.NaverCafe.domain.bulletinBoard.dto;

import static CloneCoding.NaverCafe.domain.bulletinBoard.enums.BasicBulletinBoardData.DESCRIPTION;
import static CloneCoding.NaverCafe.domain.bulletinBoard.enums.BasicBulletinBoardData.GENERAL_NAME;
import static CloneCoding.NaverCafe.domain.cafeMember.enums.CafeMemberPosition.CAFE_MEMBER;

@Getter
public class ResponseGeneralCreateForm {

    public ResponseGeneralCreateForm() {
        this.name = GENERAL_NAME.getValue();
        this.description = DESCRIPTION.getValue();
        this.writeAuth = CAFE_MEMBER.getPosition();
        this.readAuth = CAFE_MEMBER.getPosition();
        this.commentAuth = CAFE_MEMBER.getPosition();
        this.useFavorite = true;
    }

    private final String name;

    private final String description;

    private final String writeAuth;

    private final String readAuth;

    private final String commentAuth;

    private final boolean useFavorite;

}

 

  일반 게시판 생성 요청시, 생성 양식에 사용될 기본 데이터를 전달하는 DTO 클래스이다. 기본 생성자로 생성시 전달할 기본 데이터로 모든 필드가 초기화된다.


RequestCreateGeneralBulletinBoard

package CloneCoding.NaverCafe.domain.bulletinBoard.dto;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class RequestCreateGeneralBulletinBoard {

    @NotNull
    private int sequence;

    @NotBlank(message = "메뉴명을 입력해주세요")
    private String name;

    @NotNull
    private String description;

    @NotNull
    private String writeAuth;

    @NotNull
    private String readAuth;

    @NotNull
    private String commentAuth;

    @NotNull
    private boolean useFavorite;

}

 

  일반 게시판 생성 요청 정보를 전달하는 DTO 클래스이다.


BulletinBoardController

package CloneCoding.NaverCafe.domain.bulletinBoard.controller;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/manageMenu")
public class BulletinBoardController {

    private final BulletinBoardService bulletinBoardService;

    @GetMapping("/create/general")
    public ResponseGeneralCreateForm getGeneralCreateForm(@RequestHeader("Authorization") String token) {
        log.info("일반 게시판(통합게시판) 생성 양식 요청");
        return bulletinBoardService.createGeneralForm(token);
    }

    @PostMapping("/create/general/{cafe_url}")
    public String createGeneralBulletinBoard(@PathVariable("cafe_url") String url,
                                             @RequestBody @Valid RequestCreateGeneralBulletinBoard request,
                                             @RequestHeader("Authorization") String token) {
        log.info("일반 게시판(통합게시판) 생성 요청");
        return bulletinBoardService.createGeneralBulletinBoard(request, url, token);
    }

}

 

  • getGeneralCreateForm() : 토큰 정보로 BulletinBoardService의 createGeneralForm()을 호출, 결과를 반환
  • createGeneralBulletinBoard() : 카페 URL, 요청 정보, 토큰 정보로 BulletinBoardService의 createGeneralBulletinBoard()를 호출, 결과를 반환

BulletinBoardServiceImpl

package CloneCoding.NaverCafe.domain.bulletinBoard.service;

import static CloneCoding.NaverCafe.message.SystemMessage.SUCCESSFULLY_REFLECT;

@Service
@RequiredArgsConstructor
public class BulletinBoardServiceImpl implements BulletinBoardService {

    private final BulletinBoardRepository bulletinBoardRepository;
    private final MemberRepository memberRepository;
    private final CafeRepository cafeRepository;
    private final CafeMemberRepository cafeMemberRepository;
    private final AesUtil aesUtil;

    @Override
    public ResponseGeneralCreateForm createGeneralForm(String token) {
        checkMember(token);
        return new ResponseGeneralCreateForm();
    }

    @Override
    public String createGeneralBulletinBoard(RequestCreateGeneralBulletinBoard request,
                                             String url, String token) {

        Cafe cafe = cafeRepository.findByUrl(url);
        checkCafeMember(cafe, token);

        BulletinBoard bulletinBoard = BulletinBoard.createGeneralBulletinBoard(cafe, request);

        bulletinBoardRepository.save(bulletinBoard);

        return SUCCESSFULLY_REFLECT.getMessage();

    }

    private void checkMember(String token) {
        String accountId = aesUtil.aesDecode(token);
        memberRepository.findByAccountId(accountId);
    }

    private void checkCafeMember(Cafe cafe, String token) {
        String accountId = aesUtil.aesDecode(token);
        cafeMemberRepository.findByAccountId(cafe, accountId);
    }

}

 

  • createGeneralForm() : 일반 게시판 생성양식을 만드는 메서드로 ResponseGeneralCreateForm() 객체를 반환
  • createGeneralBulletinBoard() : 일반 게시판을 생성하는 메서드로 결과 메시지를 반환
  • checkMember() : 네이버 회원 확인 메서드
  • checkCafeMember() : 카페 회원 확인 메서드

API TEST

API TEST - 일반 게시판 생성양식 요청

 

  일반 게시판 생성양식에 필요한 데이터를 호출한 결과이다. 사용자에게 제공될 기본 데이터가 반환된 것을 확인할 수 있다.

 

API TEST - 일반 게시판 추가

 

DB - 일반 게시판 추가 결과

 

  일반 게시판 추가 요청 테스트, 사용자가 입력한 데이터로 일반 게시판이 잘 생성된 것을 반환 메시지로 확인했으며, DB를 통해서 카페 생성시에 자동으로 생성되는 자유게시판 외에 추가적으로 게시판이 생긴 것을 확인 할 수 있다.


수정사항 (24.05.29)

  기존에 작성한 BulletinBoard라는 클래스명이 너무 길어 고민이었다. 다른 짧은 단어로 바꾸자니 어떤 의미인지 파악하는데 어려움이있고 그대로 하자니 추가적으로 동일 도메인의 컨트롤러, 서비스, 레포지토리의 모든 이름이 길어지고 심지어 메서드명 조차 길어져 너무 불편하였다. 때문에 도메인 패키지 아래에 menu.normal.integrate 패키지를 순차적으로 만들어 패키지 경로까지 보면 '메뉴-일반-통합'이라는 의미를 부가적으로 알 수 있도록 하였고, 기본적으로 네이버에서도 게시판 목록을 '메뉴'로 지칭하며 하위에 일반, 기본 등의 메뉴를 가지며 각각 그 아래로 여러 타입의 게시판을 가지기에 납득 할 만한 수정이었다고 생각한다.