ToBe끝판왕

[ API ] 간단 Restful CRUD API 포스트맨 테스트 ( SpringBoot + Gradle + MyBatis + Mysql ) 본문

■ 공부 기록/기능 구현

[ API ] 간단 Restful CRUD API 포스트맨 테스트 ( SpringBoot + Gradle + MyBatis + Mysql )

업그레이드중 2025. 1. 2. 23:21
반응형

 

 

 


 

 

SpringBoot + 간단한 CRUD Api

 

 

 

1) Spring initializr 사용하여 SpringBoot 프로젝트 생성

 

 

 

https://start.spring.io/

 

 

 

•  Project  :  사용할 빌드 툴 선택

•  Language  :  사요할 개발 언어 선택

•  Spring Boot  :  Spring Boot 버전 선택

 

 

 

※ SNAPSHOT 이라고 명시된 버전은 현재 개발중인 데모버전 이므로 써있지 않은 버전을 선택한다.

 

•  Group  :  기업 도메인명

•  Artifact  :  빌드된 후 나올 결과물

•  Name  :  프로젝트 명  ( 일반적으로 Artifact 명과 동일시 한다. )

•  Description  :  설명 package 이름 ( Group과 Artifact를 설정하면 자동으로 설정 됨 )

•  Package name  :  패키지 이름. 위 항목에 작성한 내용에 맞춰 자동 생성된다.

•  Packaging  :  기본이 .jar 이다. ( Srping Framework와 Model2는 .war 를 사용 )

•   Java  :  Java 버전 선택

 

 

 

※  스프링 부트 3.0 이상 버전 시, JDK 17 이상을 사용해야 한다.

 

•  Dependencies  :  필요한 라이브러리를 끌어와서 세팅할 수 있다.

•   SrpingWeb  :  웹 서비스를 만드는 데 가장 중요한 모듈이다. 내장 톰캣 뿐 아니라 REST API 구축, 서버 통신,

                            데이터 직렬화 등 웹 애플리케이션 개발에 필수적인 여러 기능을 제공하여 스프링 부트 프로젝트에서

                             핵심적인 역할을 합니다.

•  Lombok  :  반복적인 코드를 줄일 수 있고, 특히 데이터 모델링 클래스에서 반복되는 getter/setter, toString, equals,                                 hashCode 메서드, 생성자 등 다양한 보일러플레이트 코드를 자동으로 생성 가능 해진다.

 

 

▶  하단에 GENERATE 버튼을 클릭하면 세팅한 내용을 기반으로 프로젝트가 자동으로 다운 받아진다.

 

 

 

•  압축파일로 받아진 프로젝트 파일 압축 해제를 해준다.

•  InteliJ에서 open을 클릭한 후, 해당 파일의 [ build.gradle ]를 누르면 프로젝트가 열린다.

 

 

 

•  프로젝트를 연 후, main/java 폴더 아래에 있는 메인.java 파일을 실행해본다.

•  localhost:8080/ 에 접속하여 아래와 같은 에러 페이지가 뜨면 정상적으로 된것이다.

 

 

 

 


 

 

 

 

2) 기본적인 CRUD Rest API  + Postman 사용

 


💡 REST API  :  REST 기반으로 만들어진 API



💡  REST ( = Representational State Trasnfer )
-  웹 서비스를 개발하는데 사용되는 아키텍처 스타일로써, 자원을 이름으로 구분하여
   해당 자원의 상태를 주고 받는것을 의미

-  HTTP URI ( = Uniform Resource Identifier ) 을 통해 자원 ( Resources )을 명시하고
   HTTP Method ( POST , GET , PUT , DELETE , PATCH ) 을 통해 해당 자원 ( URI ) 에
   대한 CRUD Operation 을 적용하는 것을 의미

※ 자원 ( Resources )
-  데이터를 나타내는 추상적인 개념으로 URI 로 식별 된다.

※  REST API 의 표현
-  자원의 상태를 나타내며, 일반적으로 JSON 이나 XML 형식 사용


💡  HTTP METHOD 와 CRUD 

-  POST 
•  주로, 데이터를 생성하기 위해 사용 ( Create )
•  요청 본문에 생성할 자원의 정보를 표현
•  Body 가 있다.

-  GET
•  데이터를 조회하기 위해 사용 ( Select )
•  서버 데이터를 변경하지 않으므로 안전성이 높다. ( 읽기 전용 )
•  요청 URL에 조회 조건을 포함하여 원하는 데이터를 선택적으로 가져올 수 있다.
•  Body 가 없다

-  PUT
•  데이터를 수정하기 위해 사용 ( Update )
•  요청 본문에 업데이트된 전체 자원 정보를 포함
•  Body 가 있다.

-  DELETE
•  데이터를 삭제하기 위해 사용 ( Delete )
•  Body 가 없다.

-  PATCH
•  리소스의 일부분을 업데이트
•  요청 본문에 변경사항만 포함

※ PUT 과 PATCH 의 차이
-  PUT  :  요청에 포함된 데이터로 기존의 리소스를 완전히 대체
               ( 요청에 포함된 모든 정보가 새로운 자원의 상태 정의 )

-  PATCH  :  요청에 포함된 데이터로 기존 자원을 부분적으로 수정
                    ( 변경하고 싶은 부분만 명시적으로 지정 )

 

 

 

 

-  HTTP 메서드 비교표

HTTP
Method
사용 용도 데이터 포함 위치 주요 특징
GET 조회 URL 쿼리 ( = 쿼리 파라미터 ) 읽기 전용, 캐싱 기능
POST 생성 요청 본문 ( Body ) 서버 상태 변경
PUT 생성 / 대체 요청 본문 ( Body ) 전체 리소스 수정  또는 생성
PATCH 부분 수정 요청 본문 ( Body ) 리소스 일부분만 수정
DELETE 삭제 URL 리소스 삭제

 

 

 

 

-  Postman 설치

https://www.postman.com/downloads/

 

Download Postman | Get Started for Free

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

www.postman.com

 

 

 

 

-  URI 경로 설정

HTTP
METHOD
경로 설명
GET /board 게시판 전체 조회
GET /board?userId={userId} 회원ID에 해당하는 게시판만 조회
POST /board 게시판 등록
PUT /board/{seq} seq에 해당하는 게시판 수정
DELETE /board/{seq} seq에 해당하는 게시판 삭제

 

 

 

 

-  프로젝트 구조 설정

 

•  프로젝트 디렉터리 구조

 

 

 

•  application.properties 설정

#Server Port
server.port = 8080

# MySQL DataSource Setting
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=#{RDS 인스턴스 주소 }
spring.datasource.username=#{Id}
spring.datasource.password=#{Password}

# MyBatis Setting
mybatis.mapper-locations=classpath:mybatis/mapper/**/*.xml

 

 

 


 

 

 

3) 소스 구현

 

 

BoardDto 클래스

 

※  @Data 어노테이션

•  Lombok 자바 라이브러리에서 제공

•  getter / setter 메서드 자동 생성

•  toString , equals , hashCode 자동 생성

•  @RequiredArgsConstructor 생성

package com.spring.blogCrudApi.dto;

import lombok.Data;

@Data
public class BoardDto {

    private int seq;
    private String boardTitle;
    private String boardContent;
    private String userId;

}

 

 

 

BoardController 생성

 

※  @RestController 어노테이션 사용

•  주로 Restful API 개발하는 경우 사용

•  @Controller 어노테이션 + @ResponseBody 어노테이션을 하나로 합친 형태

•  해당 클래스가 Controller 임을 명시하고, 메서드의 Return 값을 HTTP 응답 본문에 직접 반환하도록 지시

 

 

※  @RequestParam 어노테이션 사용

•  HTTP 요청 파라미터( = 쿼리 파라미터 ex) /board?seq=1 )를 메서드의 매개변수로 매핑하는 어노테이션

•  value  :  요청 파라미터의 이름 설정

•  required  :  해당 파라미터가 필수값인지 설정 ( false 라면 파라미터가 없어도 메서드는 정상적으로 호출 )

 

 

※  @RequestBody 어노테이션 사용

•  Spring MVC에서 HTTP 요청의 본문 Body 에 담긴 데이터를 자바객체로 변환하여 메서드의 파라미터로 사용

•  JSON , XML 형식의 복잡한 데이터를 처리할때 유용하다.

•  클라이언트 ( 사용자 )에서 전송한 데이터를 자동으로 객체의 프로퍼티에 매핑해준다.

•  @RequestBody 에 지정된 객체의 프로퍼티 이름과 요청한 JSON데이터의 Key 값이 일치해야 한다.

 

 

※  @PathVariable 어노테이션 사용

•  Spring MVC에서 HTTP 요청의 본문 Body 에 담긴 데이터를 자바객체로 변환하여 메서드의 파라미터로 사용

•  URL에 변수를 포함하여 다양한 경의 수를 동적으로 처리가 가능토록 한다.

•  @PathVariable 을 사용하기 위해서는 URL에 { } 안 변수 이름을 지정해야 한다.

•  @PathVariable 에 지정된 변수 타입과 URL에서 추출된 값의 타입이 일치해야 한다.

package com.spring.blogCrudApi.controller;

import com.spring.blogCrudApi.dto.BoardDto;
import com.spring.blogCrudApi.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
public class BoardController {

    private final BoardService boardService;

    @Autowired
    public BoardController(BoardService boardService) {
        this.boardService = boardService;
    }

    /**
     * Restful API Get 메서드
     * @param userId
     * @return
     */
    @GetMapping("/board")
    public List<BoardDto> boardList(@RequestParam(value = "userId", required = false) String userId) {

        if(userId == null ) {
            return boardService.selectAllBoardList();
        }

        return boardService.selectListByUserId(userId);
    }

    /**
     * Restful API POST 메서드
     * @param boardDto
     * @return
     */
    @PostMapping("/board")
    public Map<String, Object> createBoard(@RequestBody BoardDto boardDto) {

        return boardService.insertBoard(boardDto);
    }

    /**
     * Restful API PUT  메서드
     * @param seq
     * @param boardDto
     * @return
     */
    @PutMapping("/board/{userId}")
    public Map<String, Object> updateBoard(@PathVariable int seq, @RequestBody BoardDto boardDto) {

        boardDto.setSeq(seq);
        return boardService.updateBoard(boardDto);
    }

    /**
     * Restful API DELETE 메서드
     * @param seq
     * @return
     */
    @DeleteMapping("/board/{seq}")
    public Map<String, Object> deleteBoard(@PathVariable int seq) {

        return boardService.deleteBoard(seq);
    }
}

 

 

 

 

-  Service 클래스 / Mapper 인터페이스 / Mapper.xml 작성

 

※  @Param 어노테이션

•  MyBatis 와 같은 ORM 프레임워크에서 SQL쿼리에 전달되는 파라미터를 명확하게 지정하기 위해

   사용되는 어노테이션 ( 주로 MyBatis 프레임워크에서 사용 )

•  파라미터 이름이 변경되더라도 SQL 쿼리부분만 수정하면 된다. ( 유지보수 용이 )

 

package com.spring.blogCrudApi.service;

import com.spring.blogCrudApi.dto.BoardDto;
import com.spring.blogCrudApi.mapper.BoardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class BoardService {

    private final BoardMapper boardMapper;

    @Autowired
    public BoardService(BoardMapper boardMapper) {
        this.boardMapper = boardMapper;
    }

    public List<BoardDto> selectAllBoardList() {
        return boardMapper.selectAllBoardList();
    }

    public List<BoardDto> selectListByUserId(String userId) {

        return boardMapper.selectListByUserId(userId);
    }

    public Map<String, Object> insertBoard(BoardDto boardDto) {

        Map<String, Object> resultMsg = new HashMap<>();

        try {

            int resultCnt = boardMapper.insertBoard(boardDto);

            if( resultCnt == 1 ) {
                resultMsg.put("SUCCESS", "게시판 등록에 성공하셨습니다");

            } else {
                resultMsg.put("FAIL", "게시판 등록에 실패하셨습니다");
            }

        } catch (Exception e) {
            resultMsg.put("ERROR", "시스템 오류가 발생하였습니다.");
        }

        return resultMsg;
    }

    public Map<String, Object> updateBoard(BoardDto boardDto) {

        Map<String, Object> resultMsg = new HashMap<>();

        try {

            int resultCnt = boardMapper.updateBoard(boardDto);

            if( resultCnt == 1 ) {
                resultMsg.put("SUCCESS", "게시판 수정에 성공하셨습니다");

            } else {
                resultMsg.put("FAIL", "게시판 수정에 실패하셨습니다");
            }

        } catch (Exception e) {
            resultMsg.put("ERROR", "시스템 오류가 발생하였습니다.");
        }

        return resultMsg;
    }

    public Map<String, Object> deleteBoard(int seq) {

        Map<String, Object> resultMsg = new HashMap<>();

        try {

            int resultCnt = boardMapper.deleteBoard(seq);

            if( resultCnt == 1 ) {
                resultMsg.put("SUCCESS", "게시판 삭제에 성공하셨습니다");

            } else {
                resultMsg.put("FAIL", "게시판 삭제에 성공하셨습니다");

            }

        } catch (Exception e ) {
            resultMsg.put("ERROR", "시스템 오류가 발생하였습니다.");
        }

        return resultMsg;
    }
}

 

 

package com.spring.blogCrudApi.mapper;

import com.spring.blogCrudApi.dto.BoardDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface BoardMapper {
    List<BoardDto> selectAllBoardList();

    List<BoardDto> selectListByUserId(@Param("userId") String userId);

    int insertBoard(BoardDto boardDto);

    int updateBoard(BoardDto boardDto);

    int deleteBoard(int seq);
}

 

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.spring.blogCrudApi.mapper.BoardMapper">

    <select id="selectAllBoardList" resultType="com.spring.blogCrudApi.dto.BoardDto">
        SELECT   SEQ            /* 글번호 */
               , BOARD_TITLE    /* 글제목 */
               , BOARD_CONTENT  /* 글내용 */
               , USER_ID        /* 사용자아이디 */
         FROM  BOARD
    </select>

    <select id="selectListByUserId" resultType="com.spring.blogCrudApi.dto.BoardDto">
        SELECT
                 SEQ            /* 글번호 */
               , BOARD_TITLE    /* 글제목 */
               , BOARD_CONTENT  /* 글내용 */
         FROM  BOARD
        WHERE USER_ID = #{userId}
    </select>

    <insert id="insertBoard" parameterType="com.spring.blogCrudApi.dto.BoardDto">
        INSERT  INTO BOARD
        VALUES
                ( #{boardTitle}, #{boardContent}, #{userId} )
    </insert>

    <update id="updateBoard" parameterType="com.spring.blogCrudApi.dto.BoardDto" >
        UPDATE BOARD
           SET BOARD_TITLE = #{boardTitle}
               BOARD_CONTENT = #{boardContent}
               USER_ID = #{userId}
         WHERE SEQ = #{seq}
    </update>

    <delete id="deleteBoard" >
        DELETE
          FROM BOARD
         WHERE SEQ = #{seq}
    </delete>

</mapper>

 

 

 


 

 

4) PostMan 사용하여 테스트 진행해보기

 

 

 

-  Get 메서드 테스트

 

•  HTTP 메서드 지정 ( GET )

•  Controller 의 해당 메서드 URL 입력

•  Send 버튼을 누르면 하단에 결과 도출

•  회원ID로 조회는 쿼리파라미터 Keyt-Value 값을 사용하여 전송

 

BoardList 전체 조회

 

 

쿼리파라미터의 사용자 ID 값으로 BoardList 조회

 

 

 

-  POST 메서드 테스트

 

•  HTTP 메서드 지정 ( POST )

•  Controller 의 해당 메서드 URL 입력

•  Send 버튼을 누르면 하단에 결과 도출

•  POST 메서드의 경우 HTTP 요청 Body 에 데이터들을 넣고 요청 ( JSON 형태 )

•  게시글 등록 성공/실패/에러 에 따른 결과메시지 도출

 

 

 

 

-  PUT 메서드 테스트 / DELETE 메서드 테스트

 

•  HTTP 메서드 지정 ( PUT / DELETE )

•  PUT 메서드의 경우 대체하고자 하는 데이터를 HTTP 본문 Body 에 넣는다.

•  DELETE 메서드의 경우 요청 데이터 필요 X ( URL 에 seq 값 )

 

seq 를 사용하여 UpdateBoard

 

 

seq를 사용하여 deleteBoard

 

 

모든 과정 이후 전체 BoardList 조회

 

 

 

 

 

반응형
Comments