[인프런 워밍업 클럽 0기] BE 4일차 과제
문제 1
우리는 작은 과일 과게를 운영하고 있습니다. 과일 가게에 입고된 "과일 정보"를 저장하는 API를 만드는 스펙은 다음과 같습니다.
HTTP method:
POSTHTTP path:
/api/v1/fruitHTTP 요청 Body
{
"name": String,
"warehousingDate": LocalDate,
"price": long
}HTTP요청 Body 예시
{
"name": "사과",
"warehousingDate": "2024-02-01",
"price": 5000
}응답: 성공시 200
Controller
@RestController
public class FruitController {
private final JdbcTemplate jdbcTemplate;
public FruitController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@PostMapping("/api/v1/fruit") // POST /api/v1/fruit
public void saveFruit(@RequestBody FruitCreateRequest request) {
String sql = "INSERT INTO fruit (name, warehousingDate, price) VALUES (?, ?, ?)";
jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice());
}
}Request
public class FruitCreateRequest {
private String name;
private LocalDate warehousingDate;
private long price;
public String getName() {
return name;
}
public LocalDate getWarehousingDate() {
return warehousingDate;
}
public long getPrice() {
return price;
}
}시행착오
DB를 library 밖에 만들면 기존 프로젝트에서 연동이 안 되어
MySQL 콘솔에 use fruit를 쓰지 않고 use library를 한 뒤
Fruit 테이블을 databases에 만들었다가 library 내부에 다시 만들어 참조함
실행 결과


한 걸음 더!
위 API에서
long을 사용한 이유가격의 최댓값을 고려하여 DB에서 가장 큰 bigint를 사용한다. 따라서 자바에서 long 작성하게 된다.
문제 2
과일이 팔리게 되면, 우리 시스템에 팔린 과일 정보를 기록해야 합니다. 스펙은 다음과 같습니다.
HTTP method:
PUTHTTP path:
/api/v1/fruit
HTTP 요청 Body
{
"id": long
}HTTP 요청 Body 예시
{
"id": 3
}응답 : 성공시 200
문제 3과 같이 보았을 때, 요구사항은 id를 기준으로 팔린 과일을 반영하고자 하는 것으로 보입니다.
우선, id를 요청하면 해당 과일이 존재할 경우 그 과일의 is_sold를 기본값 False에서 True로 바꿔봅시다.
(사실 요구사항이 정확히 맞는지는 모르겠음) 연습이니까 Update Code Kata 라고 생각하고 걍 해보자
Controller
@PutMapping("/api/v1/fruit")
public void updateFruit(@RequestBody FruitUpdateRequest request) {
String readSql = "SELECT id from fruit WHERE id = ?";
boolean isUserNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
if (isUserNotExist) {
throw new IllegalArgumentException();
}
String sql = "UPDATE fruit SET is_sold = TRUE WHERE id = ?";
jdbcTemplate.update(sql,request.getId());
}실행 결과

변경 전

변경 후

존재하지 않는 ID 호출 시
500 에러 확인
문제 3
우리는 특정 과일을 기준으로 팔린 금액, 팔리지 않은 금액을 조회하고 싶습니다.
예를 들어
(1, 사과, 3000원, 판매 O)
(2, 사과, 4000원, 판매 X)
(3, 사과, 3000원, 판매 O)
와 같은 세 데이터가 있다면 우리의 API는 판매된 금액: 6000원, 판매되지 않은 금액 : 4000원 이라고 응답해야 합니다.
HTTP method:
GETHTTP path:
/api/v1/fruit/stat
HTTP query
name: 과일 이름
예시
GET /api/v1/fruit/stat?name=사과HTTP 응답 Body
{
"salesAmount": long,
"notSalesAmount": long
}HTTP 응답 Body 예시
{
"salesAmount": 6000,
"notSalesAmount": 4000
}TotalPriceResponse
public class TotalPriceResponse {
private final long salesAmount;
private final long notSalesAmount;
public TotalPriceResponse(long salesAmount, long notSalesAmount) {
this.salesAmount = salesAmount;
this.notSalesAmount = notSalesAmount;
}
public long getSalesAmount() {
return salesAmount;
}
public long getNotSalesAmount() {
return notSalesAmount;
}
}Controller
@GetMapping("/api/v1/fruit/stat") // GET /api/v1/fruit/stat
public TotalPriceResponse getTotalPrice(@RequestParam String name) {
String tSql = "SELECT SUM(price) FROM fruit WHERE name = ? AND is_sold = true";
String fSql = "SELECT SUM(price) FROM fruit WHERE name = ? AND is_sold = false";
long salesAmount = jdbcTemplate.queryForObject(tSql, long.class, name);
long notSalesAmount = jdbcTemplate.queryForObject(fSql, long.class, name);
return new TotalPriceResponse(salesAmount, notSalesAmount);
}실행 결과


댓글을 작성해보세요.