[인프런 워밍업클럽 BE] 4일차 : API 만들기 with MYSQL

진욱 홍·2024년 2월 22일
0
post-thumbnail

들어가기 전

이번 과제는 MYSQL DB와 연동하여 API를 만드는 과제이다. 문제의 조건에 맞추기 위해 작성자는 다음과 같이 fruits 라는 테이블을 만들었다.

create table fruits(
    id bigint auto_increment,
    name varchar(30),
    warehousingDate DATE,
    price long,
    sales boolean default '0',
    primary key (id)
);

id는 레코드 하나 생길때마다 자동으로 증가하게 하였다.
sales는 문제 3번 판매 여부를 판별하기 위해 추가하였고 디폴트값은 0(안팔림) 이다.

문제 1

우리는 작은 과일 가게를 운영하고 있습니다. 과일 가게에 입고된 "과일 정보" 를 저장하는 API를 만들어 봅시다. 스펙은 아래와 같다.

  • HTTP method: POST
  • HTTP path: /api/v1/fruit
  • HTTP 요청 Body 예시

    {
    "name":"사과",
    "warehousingDate":"2024-02-01",
    "price":5000
    }

Controller

@RestController
public class HomeworkSecondController {

    private final JdbcTemplate jdbcTemplate;

    public HomeworkSecondController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    //문제1
    @PostMapping("/api/v1/fruit")
    public FruitInformation fruitInformation(@RequestBody FruitInformation information){
        String sql="insert into fruits(name,warehousingDate,price,sales) values(?,?,?,?)";
        jdbcTemplate.update(sql,information.getName(),information.getWarehousingDate(),information.getPrice(),information.getSales());
        return information;
    }

}

Request dto

public class FruitInformation {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDate getWarehousingDate() {
        return warehousingDate;
    }

    public void setWarehousingDate(LocalDate warehousingDate) {
        this.warehousingDate = warehousingDate;
    }

    public long getPrice() {
        return price;
    }

    public void setPrice(long price) {
        this.price = price;
    }
    public void setSales(boolean sales) {
        this.sales = sales;
    }

    private String name;
    private LocalDate warehousingDate;
    private long price;
    private boolean sales;

    public boolean getSales(){
        return sales;
    }
}

실행 결과


fruits 테이블에 '배' 데이터가 정상적으로 들어온것을 확인하였다.

문제 2

과일이 팔리게 되면, 우리 시스템에 팔린 과일 정보를 기록해야 한다. 스팩은 아래와 같다.

  • HTTP method: PUT
  • HTTP path: /api/v1/fruit
  • HTTP 요청 Body 예시
{
"id":3
}

Controller

@RestController
public class HomeworkSecondController {

    private final JdbcTemplate jdbcTemplate;

    public HomeworkSecondController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    //문제2
    @PutMapping("/api/v1/fruit")
    public void fruitId(@RequestBody FruitId fruitId){
        String sql="select * from fruits where id =? ";
        boolean empty = jdbcTemplate.query(sql, ((rs, rowNum) -> 0), fruitId.getId()).isEmpty();
        if (empty){
            throw new IllegalArgumentException();
        }
    }

}

해당하는 id가 없으면 IllegalArgumentException 예외를 띄우게 하였다.

실행 결과



해당되는 id가 있으면 200, 없으면 500에러를 띄우는 것을 확인할 수 있다.

문제 3

Controller

@RestController
public class HomeworkSecondController {

    private final JdbcTemplate jdbcTemplate;

    public HomeworkSecondController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    //문제3
    @GetMapping("/api/v1/fruit/stat")
    public FruitResponse fruitResponse(@RequestParam String name){
        String readsql="select * from fruits where name = ? ";
        boolean empty = jdbcTemplate.query(readsql, ((rs, rowNum) -> 0), name).isEmpty();
        if (empty){
            throw new IllegalArgumentException();
        }
        String notSales="select coalesce(sum(price),0) from fruits where name = ? and sales = 0";
        String Sales="select coalesce(sum(price),0) from fruits where name = ? and sales = 1";

        return new FruitResponse(jdbcTemplate.queryForObject(Sales, Long.class,name),jdbcTemplate.queryForObject(notSales, Long.class,name));
    }



}

Sales,notSales sql select 문을 자세히 보면 coalesce(sum(price),0) 라 적혀 있다. 이는 해당되는 조건에 맞는 레코드가 없으면 0을 반환한다.
해당되는 과일이 전부 팔렸거나 전부 팔리지 않았을 수도 있기 때문이다. 만약 coalesce(sum(price),0) 대신 sum(price) 라 적으면 null 500 에러가 발생하였다.

Response dto

public class FruitResponse {
    private long salesAmount;
    private long notSalesAmount;
    public FruitResponse(long salesAmount, long notSalesAmount) {
        this.salesAmount = salesAmount;
        this.notSalesAmount = notSalesAmount;
    }

    public long getSalesAmount() {
        return salesAmount;
    }

    public void setSalesAmount(long salesAmount) {
        this.salesAmount = salesAmount;
    }

    public long getNotSalesAmount() {
        return notSalesAmount;
    }

    public void setNotSalesAmount(long notSalesAmount) {
        this.notSalesAmount = notSalesAmount;
    }
}

실행 결과

현재 fruits 테이블은 아래와 같이 구성 되어있다고 하자. sales가 0이면 판매X, 1이면 판매O 이다.


정상적으로 실행되는 것을 확인할 수 있다.

강의 출처: https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%84%9C%EB%B2%84%EA%B0%9C%EB%B0%9C-%EC%98%AC%EC%9D%B8%EC%9B%90/dashboard

profile
Geospatial Information Engineering · Computer Science&Engineering

0개의 댓글