[Practice] 게시판 API 만들기 (1)

2021. 4. 16. 12:58Spring/Practice

1. 문제

  • 게시판 타입을 추가하는 API
  • 동일한 게시판 제목이 있는 경우 status: 200, result: false, message: "이미 동일한 게시판이 존재합니다." 리턴
  • 게시판 이름은 필수항목에 대한 부분 체크

 

 

 

2. 풀이

- schema.sql

DROP TABLE IF EXISTS USER;
DROP TABLE IF EXISTS NOTICE;

create table USER (
    ID          BIGINT auto_increment primary key,
    EMAIL       VARCHAR(255),
    NAME        VARCHAR(255),
    PASSWORD    VARCHAR(255),
    PHONE       VARCHAR(255),
    REG_DATE    TIMESTAMP,
    UPDATE_DATE TIMESTAMP,
    STATUS      INTEGER,
    LOCK_YN     BOOLEAN DEFAULT FALSE
);

create table NOTICE (
    ID          BIGINT auto_increment primary key,
    TITLE       VARCHAR(255),
    CONTENTS    VARCHAR(255),

    HITS        INTEGER,
    LIKES       INTEGER,

    REG_DATE    TIMESTAMP,
    UPDATE_DATE TIMESTAMP,
    DELETED     BOOLEAN DEFAULT FALSE,
    DELETED_DATE    TIMESTAMP,

    USER_ID     BIGINT,
    constraint FK_NOTICE_USER_ID foreign key(USER_ID) references USER(ID)
);

create table NOTICE_LIKE (
    ID          BIGINT auto_increment primary key,

    NOTICE_ID   BIGINT,
    constraint FK_NOTICE_LIKE_NOTICE_ID foreign key(NOTICE_ID) references NOTICE(ID),

    USER_ID     BIGINT,
    constraint FK_NOTICE_LIKE_USER_ID foreign key(USER_ID) references USER(ID)
);

create table USER_LOGIN_HISTORY (
    ID          BIGINT auto_increment primary key,
    USER_ID     BIGINT,
    EMAIL       VARCHAR(255),
    NAME        VARCHAR(255),
    LOGIN_DATE  TIMESTAMP,
    IP_ADDR     VARCHAR(255)
);

create table BOARD_TYPE (
    ID          BIGINT auto_increment primary key,
    BOARD_NAME  VARCHAR(255),
    REG_DATE    TIMESTAMP
);

- BoardType.java

package com.example.jpa.sample.board.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.time.LocalDateTime;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
public class BoardType {

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

    @Column
    private String boardName;

    @Column
    private LocalDateTime regDate;
}

- BoardService.java

package com.example.jpa.sample.board.service;

import com.example.jpa.sample.board.model.BoardTypeInput;
import com.example.jpa.sample.board.model.ServiceResult;

public interface BoardService {

    ServiceResult addBoard(BoardTypeInput boardTypeInput);
}

- BoardServiceImpl.java

package com.example.jpa.sample.board.service;

import com.example.jpa.sample.board.entity.BoardType;
import com.example.jpa.sample.board.model.BoardTypeInput;
import com.example.jpa.sample.board.model.ServiceResult;
import com.example.jpa.sample.board.repository.BoardTypeRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@RequiredArgsConstructor
@Service
public class BoardServiceImpl implements BoardService {

    private final BoardTypeRepository boardTypeRepository;

    @Override
    public ServiceResult addBoard(BoardTypeInput boardTypeInput) {
        BoardType boardType = boardTypeRepository.findByBoardName(boardTypeInput.getName());

        if(boardType != null && boardTypeInput.getName().equals(boardType.getBoardName())) { // 동일한 게시판 제목이 있을 경우
            return ServiceResult.fail("이미 동일한 게시판이 존재합니다.");
        }

        BoardType addBoardType = BoardType.builder()
                .boardName(boardTypeInput.getName())
                .regDate(LocalDateTime.now())
                .build();

        boardTypeRepository.save(addBoardType);

        return ServiceResult.success();
    }
}

- BoardRepository.java

package com.example.jpa.sample.board.repository;

import com.example.jpa.sample.board.entity.BoardType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BoardTypeRepository extends JpaRepository<BoardType, Long> {

    BoardType findByBoardName(String name);
}

- BoardTypeInput.java

package com.example.jpa.sample.board.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class BoardTypeInput {

    @NotBlank(message = "게시판 제목은 필수항목입니다.")
    private String name;

}

- ServiceResult.java

package com.example.jpa.sample.board.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class ServiceResult {

    private boolean result;
    private String message;

    public static ServiceResult fail(String message) {
        return ServiceResult.builder()
                .result(false)
                .message(message)
                .build();
    }

    public static ServiceResult success() {
        return ServiceResult.builder()
                .result(true)
                .build();
    }
}

- ApiBoardController.java

package com.example.jpa.sample.board.controller;

import com.example.jpa.sample.board.model.BoardTypeInput;
import com.example.jpa.sample.board.model.ServiceResult;
import com.example.jpa.sample.board.service.BoardService;
import com.example.jpa.sample.notice.model.ResponseError;
import com.example.jpa.sample.user.model.ResponseMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

@RequiredArgsConstructor
@RestController
public class ApiBoardController {

    private final BoardService boardService;

    // 문제 1
    @PostMapping("/api/board/type")
    public ResponseEntity<?> addBoardType(@RequestBody @Valid BoardTypeInput boardTypeInput, Errors errors) {

        if(errors.hasErrors()) {
            List<ResponseError> responseErrorList = ResponseError.of(errors.getAllErrors());
            return new ResponseEntity<>(ResponseMessage.fail("입력값이 정확하지 않습니다.", responseErrorList), HttpStatus.BAD_REQUEST);
        }

        ServiceResult result = boardService.addBoard(boardTypeInput);

        if(!result.isResult()) {
            return ResponseEntity.ok().body(ResponseMessage.fail(result.getMessage()));
        }

        return ResponseEntity.ok().build();
    }
}

수정

package com.example.jpa.sample.user.model;

import com.example.jpa.sample.user.entity.User;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.util.Optional;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class ResponseMessage {

    ResponseMessageHeader header;
    Object body;

    public static ResponseMessage fail(String message) {
        return fail(message, null);
    }

    public static ResponseMessage fail(String message, Object data) {
        return ResponseMessage.builder()
                .header(ResponseMessageHeader.builder()
                        .result(false)
                        .resultCode("")
                        .message(message)
                        .status(HttpStatus.BAD_REQUEST.value())
                        .build())
                .body(data)
                .build();
    }

    public static ResponseMessage success(Object data) {
        return ResponseMessage.builder()
                .header(ResponseMessageHeader.builder()
                        .result(true)
                        .resultCode("")
                        .message("")
                        .status(HttpStatus.OK.value())
                        .build())
                .body(data)
                .build();
    }

    public static ResponseMessage success() {
        return success(null);
    }
//    private Long totalCount;
//    private List<User> data;
}

 

728x90