기술블로그

CRUD 게시판 만들기 3 : 게시판 구조와 백엔드 생성 본문

Spring/Springboot + React

CRUD 게시판 만들기 3 : 게시판 구조와 백엔드 생성

hc_Jo 2021. 9. 12. 21:25

프로젝트 구조

지금 부터 구현할 게시판의 구조는 대략 위의 캡쳐와 같다.

※ 데이터 통신이 일어나는 순서

  1. 'Web Browser'에서 React 어플리케이션의 URL로 접속
  2. 'Web Browser'에서 요청한 URL에 따라 'React-Router'에서 해당 URL에 해당하는 페이지의 내용을 렌더링하는 최상위 'Component'를 불러온다.
  3. 'Component'가 렌더링 될때 'Service'에 미리 정의해둔 함수를 사용해서 데이터를 가져온다.
  4. 'Service'에서는 axios 패키지의 기능을 사용해서 'Spring boot API'와 http 통신을 주고 받는다.
  5. React쪽의 'Service'에서 요청한 http request를 'Rest Controller'에서 수신한다.
  6. 'Rest Controller'에서 'Service'를 호출하여 "React쪽의 'Service'에서 요청한 것"에 해당하는 기능을 수행한다.
  7. 'Service'에서는 'Repository'를 호출하여 데이터 crud작업을 처리한다.
  8. 'Repository'에서 'DB'를 호출하여 데이터 crud작업을 처리한다.

유저가 웹 브라우져에서 특정페이지에 접속해서 페이지의 내용을 볼 때 대략 위에 기재한 '※ 데이터 통신이 일어나는 순서' 대로 동작한다.
게시판을 구현할때도 이 기본구성과 통신의 흐름을 생각하며 코딩하면, 큰 문제없이 원하는 기능을 구현할 수 있을것이다.

서버부분 REST API

다음은 Board 리소스 용으로 개발할 5가지 REST API(Controller handler method) 입니다.

Sr. No. API Name HTTP Method Path Status Code 설명
(1) GET Boards GET /api/board 200
(OK)
모든 게시판 정보를 가져옵니다.
(2) POST Board POST /api/board 201
(Created)
새로운 게시글 생성합니다.
(3) GET Board GET /api/board/{id} 200
(OK)
하나의 게시글 정보를 가져옵니다.
(4) PUT Board PUT /api/board/{id} 200
(OK)
게시글 정보를 수정합니다.
(5) DELETE Board DELETE /api/board/{id} 204
(No Content)
게시글 정보를 삭제합니다.

 

JPA 엔티티 생성

com.board.boardback.model 이라는 새 패키지를 만들고, Board 라는 클래스를 만들어 다음 코드를 추가합니다.

// Board.java 
@Entity 
@Table(name = "board") 
@Getter @Setter 
@AllArgsConstructor @NoArgsConstructor 
public class Board { 
  @Id 
  @GeneratedValue(strategy = GenerationType.IDENTITY) 
  private Integer uid; 

  @Column(name = "title") 
  private String title; 

  @Column(name = "content") 
  private String content; 

  @Column(name = "writer") 
  private String writer; 

  @Column(name = "view_cnt") 
  private Integer viewCnt; 
 }
  • 모든 도메인 모델은 @Entity 애노테이션을 달아야 합니다.
  • @Table 애노테이션은 엔터티가 매핑될 테이블의 세부 정보를 제공하는 데 사용됩니다.
  • @Id 애노테이션은 기본 키를 정의하는 데 사용됩니다.
  • @GeneratedValue 애노테이션은 기본 키 생성 전략을 정의하는 데 사용됩니다.
  • @Column 애노테이션은 애노테이션이 있는 필드에 매핑될 열의 속성을 정의하는 데 사용됩니다.
  • @Getter, @Setter 애노태이션은 메소드를 통해 데이터 변경을 위해 사용됩니다.
  • @AllArgsConstructor @NoArgsConstructor 애노테이션은 기본 생성자를 대신 생성해줍니다.

 

데이터 저장소 생성

이제 저장소를 생성해 보겠습니다. 먼저 기본 패키지 com.board.boardback 내부에 repository 라는 새 패키지를 만듭니다 . 그런 다음 BoardRepository 인터페이스를 만들고 JpaRepository 를 extends 합니다.

//BoardRepository.java 
@Repository 
public interface BoardRepository extends JpaRepository<Board, Integer> { }

 

맞춤형 비즈니스 예외 생성

다음 섹션에서 게시판 생성, 조회, 수정 및 삭제를 위한 Rest API를 정의합니다 .
API는 데이터베이스에서 주어진 id 를 가진 게시글을 찾을 수 없을 때마다 ResourceNotFoundException 을 발생시킵니다.
기본 패키지 com.board.boardback 내부에 exception 이라는 패키지를 생성해 보겠습니다. 그런 아래 코드의 내용으로 ResourceNotFoundException 이라는 새 클래스를 만듭니다.

//ResourceNotFoundException 
@ResponseStatus(value = HttpStatus.NOT_FOUND) 
public class ResourceNotFoundException extends RuntimeException{ 
  private static final Integer serialVersionUID = 1; 

  public ResourceNotFoundException(String message) { 
  	super(message); 
  } 
}

Rest Controller 생성

이제 Board 생성, 조회, 수정 및 삭제를 위한 REST API를 생성 합니다.
먼저 com.board.boardback 내부에 새 패키지 controller 를 만듭니다. 그런 다음 아래 내용으로 새 클래스 BoardController 를 만듭니다.

@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("/api")
public class BoardController {

    @Autowired
    private BoardService boardService;

    // create board rest api
    @PostMapping("/boards")
    public Board createBoard(@RequestBody Board board) {
        return boardService.createBoard(board);
    }

    // list all boards
    @GetMapping("/boards")
    public List<Board> listAllBoards() {
        return boardService.listAllBoards();
    }

    // get board by id
    @GetMapping("/boards/{id}")
    public ResponseEntity<Board> getBoardById(@PathVariable Integer id) {
        return boardService.getBoardById(id);
    }

    // update board
    @PutMapping("/boards/{id}")
    public ResponseEntity<Board> updateBoard(
            @PathVariable Integer id, @RequestBody Board boardDetails) {
        return boardService.updateBoard(id, boardDetails);
    }

    // delete board
    @DeleteMapping("/boards/{id}")
    public ResponseEntity<Map<String, Boolean>> deleteBoard(@PathVariable Integer id) {
        return boardService.deleteBoard(id);
    }
}

@CrossOrigin : CORS 문제를 해결하기 위해 추가.

 

 

Service 만들기

@Service
public class BoardService {

    @Autowired
    private BoardRepository boardRepository;

    // create board rest api
    public Board createBoard(@RequestBody Board board) {
        return boardRepository.save(board);
    }

    // list all boards
    public List<Board> listAllBoards() {
        return boardRepository.findAll();
    }

    // get board by id
    public ResponseEntity<Board> getBoardById(@PathVariable Integer id) {
        Board board = boardRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Board not exist with id :" + id));

        int cnt = board.getViewCnt();
        board.setViewCnt(cnt + 1);

        return ResponseEntity.ok(board);
    }

    // update board
    public ResponseEntity<Board> updateBoard(@PathVariable Integer id, @RequestBody Board boardDetails) {
        Board board = boardRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Board not exist with id :" + id));

        board.setTitle(boardDetails.getTitle());
        board.setContent(boardDetails.getContent());

        Board updatedBoard = boardRepository.save(board);
        return ResponseEntity.ok(updatedBoard);
    }

    // delete board
    public ResponseEntity<Map<String, Boolean>> deleteBoard(@PathVariable Integer id) {
        Board board = boardRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("Board not exist with id :" + id));

        boardRepository.delete(board);
        Map <String, Boolean> response = new HashMap<>();
        response.put("deleted", Boolean.TRUE);
        return ResponseEntity.ok(response);
    }

}

 

애플리케이션 실행

이 스프링 부트 애플리케이션에는 애플리케이션 을 시작하기 위해 실행할 수 있는 public static void main(String[] args) 메소드가 있는 SpringbootBackendApplication 이라는 진입점 Java 클래스가 있습니다.
이것으로 Spring boot CRUD Rest API 개발이 완료되었습니다.

@SpringBootApplication 
public class BoardBackApplication { 
  public static void main(String[] args) { 
    SpringApplication.run(BoardBackApplication.class, args); 
  } 
}

POSTMAN에서 설계한 API 테스트를 합니다.

 

포스트맨 다운 링크

 

Download Postman | Try Postman for Free

Try Postman for free! Join 17 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

 

1. 생성

2. 전체 조회

3. 특정 id값 조회

- 조회수 1증가

4. 수정하기

5. 삭제하기

 

 

이렇게 테스트 해볼 수 있다.

 

 

다음은 CRUD 작업한 REST API를 React에서 사용하는 방법을 진행합니다.