From aac673a02c0310cf1586913634af1c009b7df9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=A9=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=AA=E1=86=AB=20=28Can=29?= Date: Thu, 22 Apr 2021 07:24:05 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]=20Repository=20=EB=A5=BC=20=EB=AA=A8?= =?UTF-8?q?=ED=82=B9=ED=95=98=EC=97=AC=20API=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SideDish/controller/DishController.java | 18 +- .../controller/DishExceptionHandler.java | 20 ++ .../sidedish/SideDish/domain/Category.java | 25 +++ .../domain/CategoryMockRepository.java | 17 ++ .../SideDish/domain/CategoryRepository.java | 7 + .../sidedish/SideDish/domain/Dish.java | 202 +++++++++++++++++- .../SideDish/domain/DishMockRepository.java | 54 +++++ .../SideDish/domain/DishRepository.java | 8 +- .../sidedish/SideDish/dto/CategoryDto.java | 18 +- .../SideDish/dto/DishDetailDataDto.java | 112 ---------- .../sidedish/SideDish/dto/DishDetailDto.java | 88 +++++++- .../sidedish/SideDish/dto/DishDto.java | 79 ++++--- .../sidedish/SideDish/dto/QuantityDto.java | 8 +- .../exception/DishNotFoundException.java | 7 + .../SideDish/service/CategoryService.java | 22 +- .../SideDish/service/DishService.java | 70 +++--- .../src/main/resources/application.properties | 3 +- 17 files changed, 547 insertions(+), 211 deletions(-) create mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishExceptionHandler.java create mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Category.java create mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java create mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryRepository.java create mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishMockRepository.java delete mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDataDto.java create mode 100644 backend/src/main/java/com/codesquad/sidedish/SideDish/exception/DishNotFoundException.java diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java index 553b8694f..bc40f35cd 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java @@ -25,21 +25,21 @@ public ResponseEntity> getCategories() { return ResponseEntity.ok().body(categories); } - @GetMapping("/detail/{hash}") - public ResponseEntity getDetail(@PathVariable("hash") String hash) { - DishDetailDto dishDetailDto = dishService.getDetail(hash); + @GetMapping("/detail/{detailHash}") + public ResponseEntity getDetail(@PathVariable("detailHash") String detailHash) { + DishDetailDto dishDetailDto = dishService.getDetail(detailHash); return ResponseEntity.ok().body(dishDetailDto); } - @GetMapping("/detail/{hash}/refreshable") - public ResponseEntity getDetailRefreshable(@PathVariable("hash") String hash, @RequestParam("lastUpdated") int lastUpdated) { - RefreshDto refreshDto = dishService.getDetailRefreshable(hash, lastUpdated); + @GetMapping("/detail/{detailHash}/refreshable") + public ResponseEntity getDetailRefreshable(@PathVariable("detailHash") String detailHash, @RequestParam("lastUpdated") int lastUpdated) { + RefreshDto refreshDto = dishService.getDetailRefreshable(detailHash, lastUpdated); return ResponseEntity.ok().body(refreshDto); } - @GetMapping("/detail/{hash}/quantity") - public ResponseEntity getDetailQuantity(@PathVariable("hash") String hash) { - QuantityDto quantityDto = dishService.getDetailQuantity(hash); + @GetMapping("/detail/{detailHash}/quantity") + public ResponseEntity getDetailQuantity(@PathVariable("detailHash") String detailHash) { + QuantityDto quantityDto = dishService.getDetailQuantity(detailHash); return ResponseEntity.ok().body(quantityDto); } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishExceptionHandler.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishExceptionHandler.java new file mode 100644 index 000000000..7ef2ac9fa --- /dev/null +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishExceptionHandler.java @@ -0,0 +1,20 @@ +package com.codesquad.sidedish.SideDish.controller; + +import com.codesquad.sidedish.SideDish.exception.DishNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class DishExceptionHandler { + private final Logger logger = LoggerFactory.getLogger(DishExceptionHandler.class); + + @ExceptionHandler(DishNotFoundException.class) + public ResponseEntity handleDishNotFound(DishNotFoundException e) { + logger.error(e.getMessage()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("존재하지 않는 Dish 입니다."); + } +} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Category.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Category.java new file mode 100644 index 000000000..c25d3fcd1 --- /dev/null +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Category.java @@ -0,0 +1,25 @@ +package com.codesquad.sidedish.SideDish.domain; + +public class Category { + private final long id; + private final String categoryName; + private final String endPoint; + + public Category(long id, String categoryName, String endPoint) { + this.id = id; + this.categoryName = categoryName; + this.endPoint = endPoint; + } + + public long getId() { + return id; + } + + public String getCategoryName() { + return categoryName; + } + + public String getEndPoint() { + return endPoint; + } +} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java new file mode 100644 index 000000000..931e84802 --- /dev/null +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java @@ -0,0 +1,17 @@ +package com.codesquad.sidedish.SideDish.domain; + +import java.util.Arrays; +import java.util.List; + +public class CategoryMockRepository implements CategoryRepository { + private final List categories = Arrays.asList( + new Category(1, "메인", "/main"), + new Category(2, "국", "/soup"), + new Category(3, "반찬", "/side") + ); + + @Override + public List findAll() { + return categories; + } +} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryRepository.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryRepository.java new file mode 100644 index 000000000..8d24c53bd --- /dev/null +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryRepository.java @@ -0,0 +1,7 @@ +package com.codesquad.sidedish.SideDish.domain; + +import java.util.List; + +public interface CategoryRepository { + List findAll(); +} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Dish.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Dish.java index 70c9ce238..fefe5c637 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Dish.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/Dish.java @@ -1,5 +1,205 @@ package com.codesquad.sidedish.SideDish.domain; -// TODO: +import java.util.List; + public class Dish { + private final String detailHash; + private final String image; + private final String title; + private final String description; + private final List deliveryTypes; + private final int price; + private final int salePrice; + private final List badges; + + private final List thumbImages; + private final int point; + private final String deliveryInfo; + private final int deliveryFee; + private final List detailImages; + + private final long categoryId; + private final int quantity; + + private Dish(Builder builder) { + this.detailHash = builder.detailHash; + this.image = builder.image; + this.deliveryTypes = builder.deliveryTypes; + this.title = builder.title; + this.description = builder.description; + this.price = builder.price; + this.salePrice = builder.salePrice; + this.badges = builder.badges; + + this.thumbImages = builder.thumbImages; + this.point = builder.point; + this.deliveryInfo = builder.deliveryInfo; + this.deliveryFee = builder.deliveryFee; + this.detailImages = builder.detailImages; + + this.categoryId = builder.categoryId; + this.quantity = builder.quantity; + } + + public static class Builder { + private String detailHash; + private String image; + private String title; + private String description; + private List deliveryTypes; + private int price; + private int salePrice; + private List badges; + + private List thumbImages; + private int point; + private String deliveryInfo; + private int deliveryFee; + private List detailImages; + + private long categoryId; + private int quantity; + + public Dish build() { + return new Dish(this); + } + + public Builder detailHash(String detailHash) { + this.detailHash = detailHash; + return this; + } + + public Builder image(String image) { + this.image = image; + return this; + } + + public Builder title(String title) { + this.title = title; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder deliveryTypes(List deliveryTypes) { + this.deliveryTypes = deliveryTypes; + return this; + } + + public Builder price(int price) { + this.price = price; + return this; + } + + public Builder salePrice(int salePrice) { + this.salePrice = salePrice; + return this; + } + + public Builder badges(List badges) { + this.badges = badges; + return this; + } + + + public Builder thumbImages(List thumbImages) { + this.thumbImages = thumbImages; + return this; + } + + public Builder point(int point) { + this.point = point; + return this; + } + + public Builder deliveryInfo(String deliveryInfo) { + this.deliveryInfo = deliveryInfo; + return this; + } + + public Builder deliveryFee(int deliveryFee) { + this.deliveryFee = deliveryFee; + return this; + } + + public Builder detailImages(List detailSection) { + this.detailImages = detailSection; + return this; + } + + public Builder categoryId(long categoryId) { + this.categoryId = categoryId; + return this; + } + + public Builder quantity(int quantity) { + this.quantity = quantity; + return this; + } + } + + + public String getDetailHash() { + return detailHash; + } + + public String getImage() { + return image; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public List getDeliveryTypes() { + return deliveryTypes; + } + + public int getPrice() { + return price; + } + + public int getSalePrice() { + return salePrice; + } + + public List getBadges() { + return badges; + } + + public List getThumbImages() { + return thumbImages; + } + + public int getPoint() { + return point; + } + + public String getDeliveryInfo() { + return deliveryInfo; + } + + public int getDeliveryFee() { + return deliveryFee; + } + + public List getDetailImages() { + return detailImages; + } + + + public long getCategoryId() { + return categoryId; + } + + public int getQuantity() { + return quantity; + } } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishMockRepository.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishMockRepository.java new file mode 100644 index 000000000..59d78cbe6 --- /dev/null +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishMockRepository.java @@ -0,0 +1,54 @@ +package com.codesquad.sidedish.SideDish.domain; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.codesquad.sidedish.SideDish.domain.Dish.Builder; + +public class DishMockRepository implements DishRepository { + Map dishes = new LinkedHashMap<>(); + + public DishMockRepository() { + dishes.put("HBDEF", new Builder() + .detailHash("HBDEF") + .categoryId(1) // 메인요리 + .title("[윤식당] 불고기 with Rice") + .description("윤식당 불고기메뉴의 가장 기본인 불고기라이스! (마더소스 포함)") + .badges(Arrays.asList("이벤트특가", "메인특가")) + .salePrice(31200) + .price(39000) + .point(312) + .quantity(5) + .deliveryFee(2500) + .deliveryTypes(Arrays.asList("새벽배송", "전국택배")) + .deliveryInfo("서울 경기 새벽배송 / 전국택배 (제주 및 도서산간 불가) [화 · 수 · 목 · 금 · 토] 수령 가능한 상품입니다.") + .image("https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.10000recipe.com%2Frecipe%2F6907615&psig=AOvVaw1AxHy5c8fBj1PhjR7CKark&ust=1619131482191000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKjBjvm0kPACFQAAAAAdAAAAABAI") + .thumbImages(Arrays.asList( + "https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.10000recipe.com%2Frecipe%2F6863296&psig=AOvVaw1AxHy5c8fBj1PhjR7CKark&ust=1619131482191000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKjBjvm0kPACFQAAAAAdAAAAABAN", + "https://www.google.com/url?sa=i&url=https%3A%2F%2Fmeatboxbc.com%2Fproducts%2Fkorean-stylebeef-bulgogi&psig=AOvVaw1AxHy5c8fBj1PhjR7CKark&ust=1619131482191000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKjBjvm0kPACFQAAAAAdAAAAABAS")) + .detailImages(Arrays.asList( + "https://www.google.com/url?sa=i&url=http%3A%2F%2Fwww.62life.com%2Fm%2Fgoods%2Fitem_detail_m.asp%3Fodtype%3D11%26odtype2%3D01%26gdtype%3D71%26gdcd%3D7110000741%26divcd%3D30&psig=AOvVaw1AxHy5c8fBj1PhjR7CKark&ust=1619131482191000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKjBjvm0kPACFQAAAAAdAAAAABAX", + "https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.homestaurant.co.kr%2Fgoods%2Fgoods_view.php%3FgoodsNo%3D1000000392&psig=AOvVaw1AxHy5c8fBj1PhjR7CKark&ust=1619131482191000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKjBjvm0kPACFQAAAAAdAAAAABAi" + )) + .build()); + + // TODO: main(메인) 2개, soup(국) 2개, side(반찬) 2개 예시 하드코딩으로 채워넣기 + dishes.put("", new Builder() + .build()); + } + + @Override + public List findAllByCategoryId(long categoryId) { + return dishes.values().stream() + .filter(dish -> dish.getCategoryId() == categoryId) + .collect(Collectors.toList()); + } + + @Override + public Dish findByDetailHash(String detailHash) { + return dishes.get(detailHash); + } +} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishRepository.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishRepository.java index 81b85a17b..bb0c6f9d4 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishRepository.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/DishRepository.java @@ -1,5 +1,9 @@ package com.codesquad.sidedish.SideDish.domain; -// TODO: -public class DishRepository { +import java.util.List; + +public interface DishRepository { + List findAllByCategoryId(long categoryId); + + Dish findByDetailHash(String detailHash); } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/CategoryDto.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/CategoryDto.java index 075ab680f..5df022600 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/CategoryDto.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/CategoryDto.java @@ -1,16 +1,26 @@ package com.codesquad.sidedish.SideDish.dto; +import com.codesquad.sidedish.SideDish.domain.Category; + public class CategoryDto { - private long id; - private String categoryName; - private String endPoint; + private final long id; + private final String categoryName; + private final String endPoint; - public CategoryDto(long id, String categoryName, String endPoint) { + private CategoryDto(long id, String categoryName, String endPoint) { this.id = id; this.categoryName = categoryName; this.endPoint = endPoint; } + public static CategoryDto from(Category category) { + return new CategoryDto( + category.getId(), + category.getCategoryName(), + category.getEndPoint() + ); + } + public long getId() { return id; } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDataDto.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDataDto.java deleted file mode 100644 index 45e9a1bfd..000000000 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDataDto.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.codesquad.sidedish.SideDish.dto; - -import java.util.List; - -public class DishDetailDataDto { - private final String topImage; - private final List thumbImages; - private final String productDescription; - private final int point; - private final String deliveryInfo; - private final String deliveryFee; - private final List prices; - private final List detailSection; - - private DishDetailDataDto(Builder builder) { - this.topImage = builder.topImage; - this.thumbImages = builder.thumbImages; - this.productDescription = builder.productDescription; - this.point = builder.point; - this.deliveryInfo = builder.deliveryInfo; - this.deliveryFee = builder.deliveryFee; - this.prices = builder.prices; - this.detailSection = builder.detailSection; - } - - public static class Builder { - private String topImage; - private List thumbImages; - private String productDescription; - private int point; - private String deliveryInfo; - private String deliveryFee; - private List prices; - private List detailSection; - - public DishDetailDataDto build() { - return new DishDetailDataDto(this); - } - - public Builder topImage(String topImage) { - this.topImage = topImage; - return this; - } - - public Builder thumbImages(List thumbImages) { - this.thumbImages = thumbImages; - return this; - } - - public Builder productDescription(String productDescription) { - this.productDescription = productDescription; - return this; - } - - public Builder point(int point) { - this.point = point; - return this; - } - - public Builder deliveryInfo(String deliveryInfo) { - this.deliveryInfo = deliveryInfo; - return this; - } - - public Builder deliveryFee(String deliveryFee) { - this.deliveryFee = deliveryFee; - return this; - } - - public Builder prices(List prices) { - this.prices = prices; - return this; - } - - public Builder detailSection(List detailSection) { - this.detailSection = detailSection; - return this; - } - } - - public String getTopImage() { - return topImage; - } - - public List getThumbImages() { - return thumbImages; - } - - public String getProductDescription() { - return productDescription; - } - - public int getPoint() { - return point; - } - - public String getDeliveryInfo() { - return deliveryInfo; - } - - public String getDeliveryFee() { - return deliveryFee; - } - - public List getPrices() { - return prices; - } - - public List getDetailSection() { - return detailSection; - } -} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDto.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDto.java index 2d165779d..5a0ec4c05 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDto.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDetailDto.java @@ -1,19 +1,89 @@ package com.codesquad.sidedish.SideDish.dto; +import com.codesquad.sidedish.SideDish.domain.Dish; + +import java.util.List; + public class DishDetailDto { - private final String hash; - private final DishDetailDataDto data; + private final List thumbImages; + private final int point; + private final String deliveryInfo; + private int deliveryFee; + private final List detailImages; + + private DishDetailDto(Builder builder) { + this.thumbImages = builder.thumbImages; + this.point = builder.point; + this.deliveryInfo = builder.deliveryInfo; + this.deliveryFee = builder.deliveryFee; + this.detailImages = builder.detailImages; + } + + public static DishDetailDto from(Dish dish) { + return new Builder() + .thumbImages(dish.getThumbImages()) + .point(dish.getPoint()) + .deliveryInfo(dish.getDeliveryInfo()) + .deliveryFee(dish.getDeliveryFee()) + .detailImages(dish.getDetailImages()) + .build(); + } + + private static class Builder { + private List thumbImages; + private int point; + private String deliveryInfo; + private int deliveryFee; + private List detailImages; + + public DishDetailDto build() { + return new DishDetailDto(this); + } + + + public Builder thumbImages(List thumbImages) { + this.thumbImages = thumbImages; + return this; + } + + public Builder point(int point) { + this.point = point; + return this; + } + + public Builder deliveryInfo(String deliveryInfo) { + this.deliveryInfo = deliveryInfo; + return this; + } + + public Builder deliveryFee(int deliveryFee) { + this.deliveryFee = deliveryFee; + return this; + } + + public Builder detailImages(List detailSection) { + this.detailImages = detailSection; + return this; + } + } + + public List getThumbImages() { + return thumbImages; + } + + public int getPoint() { + return point; + } - public DishDetailDto(String hash, DishDetailDataDto data) { - this.hash = hash; - this.data = data; + public String getDeliveryInfo() { + return deliveryInfo; } - public String getHash() { - return hash; + public int getDeliveryFee() { + return deliveryFee; } - public DishDetailDataDto getData() { - return data; + public List getDetailImages() { + return detailImages; } } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDto.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDto.java index e9e4531ee..ccc4b400a 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDto.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/DishDto.java @@ -1,37 +1,52 @@ package com.codesquad.sidedish.SideDish.dto; +import com.codesquad.sidedish.SideDish.domain.Dish; + import java.util.List; public class DishDto { private final String detailHash; private final String image; - private final List deliveryType; private final String title; private final String description; - private final int nPrice; - private final String sPrice; - private final List badge; - + private final List deliveryTypes; + private final int price; + private final int salePrice; + private final List badges; + private DishDto(Builder builder) { this.detailHash = builder.detailHash; this.image = builder.image; - this.deliveryType = builder.deliveryType; + this.deliveryTypes = builder.deliveryTypes; this.title = builder.title; this.description = builder.description; - this.nPrice = builder.nPrice; - this.sPrice = builder.sPrice; - this.badge = builder.badge; + this.price = builder.price; + this.salePrice = builder.salePrice; + this.badges = builder.badges; + } + + public static DishDto from(Dish dish) { + return new Builder() + .detailHash(dish.getDetailHash()) + .image(dish.getImage()) + .title(dish.getTitle()) + .description(dish.getDescription()) + .deliveryTypes(dish.getDeliveryTypes()) + .price(dish.getPrice()) + .salePrice(dish.getSalePrice()) + .badges(dish.getBadges()) + .build(); } public static class Builder { private String detailHash; private String image; - private List deliveryType; private String title; private String description; - private int nPrice; - private String sPrice; - private List badge; + private List deliveryTypes; + private int price; + private int salePrice; + private List badges; public DishDto build() { return new DishDto(this); @@ -48,11 +63,6 @@ public Builder image(String image) { return this; } - public Builder deliveryType(List deliveryType) { - this.deliveryType = deliveryType; - return this; - } - public Builder title(String title) { this.title = title; return this; @@ -63,18 +73,23 @@ public Builder description(String description) { return this; } - public Builder nPrice(int nPrice) { - this.nPrice = nPrice; + public Builder deliveryTypes(List deliveryTypes) { + this.deliveryTypes = deliveryTypes; + return this; + } + + public Builder price(int price) { + this.price = price; return this; } - public Builder sPrice(String sPrice) { - this.sPrice = sPrice; + public Builder salePrice(int salePrice) { + this.salePrice = salePrice; return this; } - public Builder badge(List badge) { - this.badge = badge; + public Builder badges(List badges) { + this.badges = badges; return this; } } @@ -87,8 +102,8 @@ public String getImage() { return image; } - public List getDeliveryType() { - return deliveryType; + public List getDeliveryTypes() { + return deliveryTypes; } public String getTitle() { @@ -99,15 +114,15 @@ public String getDescription() { return description; } - public int getnPrice() { - return nPrice; + public int getPrice() { + return price; } - public String getsPrice() { - return sPrice; + public int getSalePrice() { + return salePrice; } - public List getBadge() { - return badge; + public List getBadges() { + return badges; } } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/QuantityDto.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/QuantityDto.java index 2464a82ed..64335b4f4 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/QuantityDto.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/dto/QuantityDto.java @@ -1,13 +1,19 @@ package com.codesquad.sidedish.SideDish.dto; +import com.codesquad.sidedish.SideDish.domain.Dish; + public class QuantityDto { private final int quantity; - public QuantityDto(int quantity) { + private QuantityDto(int quantity) { this.quantity = quantity; } public int getQuantity() { return quantity; } + + public static QuantityDto from(Dish dish) { + return new QuantityDto(dish.getQuantity()); + } } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/exception/DishNotFoundException.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/exception/DishNotFoundException.java new file mode 100644 index 000000000..39fd698d6 --- /dev/null +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/exception/DishNotFoundException.java @@ -0,0 +1,7 @@ +package com.codesquad.sidedish.SideDish.exception; + +public class DishNotFoundException extends RuntimeException { + public DishNotFoundException(String detailHash) { + super(String.format("Dish does not exist: %s", detailHash)); + } +} diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/service/CategoryService.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/service/CategoryService.java index dff9cf35a..90c13dc60 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/service/CategoryService.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/service/CategoryService.java @@ -1,18 +1,28 @@ package com.codesquad.sidedish.SideDish.service; +import com.codesquad.sidedish.SideDish.domain.CategoryMockRepository; +import com.codesquad.sidedish.SideDish.domain.CategoryRepository; import com.codesquad.sidedish.SideDish.dto.CategoryDto; import org.springframework.stereotype.Service; -import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; @Service public class CategoryService { + private final CategoryRepository categoryRepository; + + public CategoryService(CategoryRepository categoryRepository) { + this.categoryRepository = categoryRepository; + } + + public CategoryService() { + this(new CategoryMockRepository()); + } + public List getList() { - return Arrays.asList( - new CategoryDto(1, "메인", "/main"), - new CategoryDto(2, "국", "/soup"), - new CategoryDto(3, "반찬", "side") - ); + return categoryRepository.findAll() + .stream().map(CategoryDto::from) + .collect(Collectors.toList()); } } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/service/DishService.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/service/DishService.java index 32a2dd259..29fe8d9a3 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/service/DishService.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/service/DishService.java @@ -1,51 +1,55 @@ package com.codesquad.sidedish.SideDish.service; -import com.codesquad.sidedish.SideDish.dto.*; +import com.codesquad.sidedish.SideDish.domain.Dish; +import com.codesquad.sidedish.SideDish.domain.DishMockRepository; +import com.codesquad.sidedish.SideDish.domain.DishRepository; +import com.codesquad.sidedish.SideDish.dto.DishDetailDto; +import com.codesquad.sidedish.SideDish.dto.DishDto; +import com.codesquad.sidedish.SideDish.dto.QuantityDto; +import com.codesquad.sidedish.SideDish.dto.RefreshDto; +import com.codesquad.sidedish.SideDish.exception.DishNotFoundException; import org.springframework.stereotype.Service; -import java.util.Arrays; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; @Service public class DishService { + private final DishRepository dishRepository; - public RefreshDto getDetailRefreshable(String hash, long lastUpdated) { - return new RefreshDto(false); + public DishService(DishRepository dishRepository) { + this.dishRepository = dishRepository; } - public QuantityDto getDetailQuantity(String hash) { - return new QuantityDto(5); + public DishService() { + this(new DishMockRepository()); } - public DishDetailDto getDetail(String hash) { - DishDetailDataDto.Builder builder = new DishDetailDataDto.Builder(); - DishDetailDataDto data = builder.topImage("topImage") - .thumbImages(Arrays.asList("thumb1", "thumb2")) - .productDescription("product is awesome") - .point(25) - .deliveryInfo("서울 코드스쿼드") - .deliveryFee("2500원") - .prices(Arrays.asList("1800원", "이게 왜 array 지?")) - .detailSection(Arrays.asList("detail1", "detail2")) - .build(); - return new DishDetailDto("HF90", data); + public RefreshDto getDetailRefreshable(String detailHash, long lastUpdated) { + // NOTE: 프론트 요구사항 귀찮다. 그냥 하드코딩으로 땜빵하자; + // NOTE: 자료형식은 yyMMddhhmm + boolean refreshable = 2104220639 > lastUpdated; + return new RefreshDto(refreshable); + } + + public QuantityDto getDetailQuantity(String detailHash) { + return QuantityDto.from(getDish(detailHash)); + } + + public DishDetailDto getDetail(String detailHash) { + return DishDetailDto.from(getDish(detailHash)); } public List getList(long categoryId) { - DishDto.Builder builder = new DishDto.Builder() - .detailHash("HF93") - .image("image url") - .deliveryType(Arrays.asList("새벽배송", "주말배송")) - .title("상품이름") - .description("배가 고픈 상품") - .nPrice(5000) - .sPrice("우리가 계산을 해야할 돈") - .badge(Arrays.asList("이벤트할인", "그냥 할인")); - List dishes = Arrays.asList( - builder.build(), - builder.build(), - builder.build() - ); - return dishes; + return dishRepository.findAllByCategoryId(categoryId) + .stream().map(DishDto::from) + .collect(Collectors.toList()); + } + + private Dish getDish(String detailHash) { + Dish dish = dishRepository.findByDetailHash(detailHash); + return Optional.ofNullable(dish) + .orElseThrow(() -> new DishNotFoundException(detailHash)); } } diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index d604e27df..466a1cd2e 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -2,7 +2,6 @@ spring.datasource.url=jdbc:mysql://localhost:3306/sidedish?autoReconnect=true&us spring.datasource.username=bat spring.datasource.password=bat1234 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - - spring.datasource.schema=classpath:schema.sql spring.datasource.initialization-mode=always +spring.jackson.serialization.INDENT_OUTPUT=true From 885cd3c6b6cc3910961ff851530cee2592671174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=A9=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=AA=E1=86=AB=20=28Can=29?= Date: Thu, 22 Apr 2021 08:54:18 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[docs]=20Swagger=20=EB=A1=9C=20API=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 24 +++++++------ .../sidedish/SideDish/config/WebConfig.java | 35 +++++++++++++++++++ .../SideDish/controller/DishController.java | 25 +++++++++---- .../domain/CategoryMockRepository.java | 6 ++-- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/backend/build.gradle b/backend/build.gradle index af732e082..ee7b74215 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -1,7 +1,7 @@ plugins { - id 'org.springframework.boot' version '2.4.5' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'java' + id 'org.springframework.boot' version '2.4.5' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' } group = 'com.codesquad.sidedish' @@ -9,17 +9,21 @@ version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' - implementation 'org.springframework.boot:spring-boot-starter-web' - developmentOnly 'org.springframework.boot:spring-boot-devtools' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - runtimeOnly 'mysql:mysql-connector-java' + implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' + implementation 'org.springframework.boot:spring-boot-starter-web' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + runtimeOnly 'mysql:mysql-connector-java' + + // swagger + implementation 'io.springfox:springfox-swagger2:2.9.2' + implementation 'io.springfox:springfox-swagger-ui:2.9.2' } test { - useJUnitPlatform() + useJUnitPlatform() } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/config/WebConfig.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/config/WebConfig.java index 571e02aa9..be2b11526 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/config/WebConfig.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/config/WebConfig.java @@ -1,9 +1,21 @@ package com.codesquad.sidedish.SideDish.config; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; +import java.util.HashSet; +import java.util.Set; + +@EnableSwagger2 @Configuration public class WebConfig implements WebMvcConfigurer { @@ -13,4 +25,27 @@ public void addCorsMappings(final CorsRegistry registry) { .allowedOrigins("*") .allowedMethods("*"); } + + @Bean + public Docket api() { + ApiInfo apiInfo = new ApiInfoBuilder() + .title("Side Dish API") + .description("Spring API made by Bat and Pyro") + .license("Apache License Version 2.0") + .version("0.1") + .build(); + + Set responseContentType = new HashSet<>(); + responseContentType.add("application/json;charset=UTF-8"); + + // http://localhost:8080/swagger-ui.html + return new Docket(DocumentationType.SWAGGER_2) + .groupName("side-dish") + .produces(responseContentType) + .apiInfo(apiInfo) + .select() + .apis(RequestHandlerSelectors.basePackage("com.codesquad.sidedish.SideDish")) // NOTE: basic-error-controller 는 문서화 하지 않음 + .paths(PathSelectors.ant("/**")) + .build(); + } } diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java index bc40f35cd..65e84f760 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/controller/DishController.java @@ -3,11 +3,18 @@ import com.codesquad.sidedish.SideDish.dto.*; import com.codesquad.sidedish.SideDish.service.CategoryService; import com.codesquad.sidedish.SideDish.service.DishService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.util.List; +@Api(tags = {"Side Dish API"}, description = "Bat 와 Pyro 가 야근하며 만든 API") @RestController public class DishController { private final CategoryService categoryService; @@ -18,44 +25,50 @@ public class DishController { this.dishService = dishService; } - @GetMapping - @RequestMapping("/categories") + @GetMapping("/categories") + @ApiOperation(value = "카테고리", notes = "요리 카테고리 목록을 반환합니다.") public ResponseEntity> getCategories() { List categories = categoryService.getList(); return ResponseEntity.ok().body(categories); } @GetMapping("/detail/{detailHash}") - public ResponseEntity getDetail(@PathVariable("detailHash") String detailHash) { + @ApiOperation(value = "요리 상세", notes = "요리의 상세 정보를 반환합니다.") + public ResponseEntity getDetail(@ApiParam("요리의 식별자") @PathVariable("detailHash") String detailHash) { DishDetailDto dishDetailDto = dishService.getDetail(detailHash); return ResponseEntity.ok().body(dishDetailDto); } @GetMapping("/detail/{detailHash}/refreshable") - public ResponseEntity getDetailRefreshable(@PathVariable("detailHash") String detailHash, @RequestParam("lastUpdated") int lastUpdated) { + @ApiOperation(value = "요리 상세 갱신", notes = "요리의 상세 정보를 갱신할 필요가 있는지 여부를 반환합니다.") + public ResponseEntity getDetailRefreshable(@ApiParam("요리의 식별자") @PathVariable("detailHash") String detailHash, @ApiParam("프론트에서 마지막으로 업데이트 한 날짜. 데이터 형식: yyMMddhhmm") @RequestParam("lastUpdated") int lastUpdated) { RefreshDto refreshDto = dishService.getDetailRefreshable(detailHash, lastUpdated); return ResponseEntity.ok().body(refreshDto); } @GetMapping("/detail/{detailHash}/quantity") - public ResponseEntity getDetailQuantity(@PathVariable("detailHash") String detailHash) { + @ApiOperation(value = "요리 수량", notes = "요리의 주문 가능한 수량을 반환합니다.") + public ResponseEntity getDetailQuantity(@ApiParam("요리의 식별자") @PathVariable("detailHash") String detailHash) { QuantityDto quantityDto = dishService.getDetailQuantity(detailHash); return ResponseEntity.ok().body(quantityDto); } @GetMapping("/main") + @ApiOperation(value = "메인 요리", notes = "메인 요리의 목록을 반환합니다.") public ResponseEntity> getMainList() { List dishes = dishService.getList(1); return ResponseEntity.ok().body(dishes); } @GetMapping("/side") + @ApiOperation(value = "반찬 요리", notes = "반찬 요리의 목록을 반환합니다.") public ResponseEntity> getSideList() { List dishes = dishService.getList(1); return ResponseEntity.ok().body(dishes); } @GetMapping("/soup") + @ApiOperation(value = "국물 요리", notes = "국물 요리의 목록을 반환합니다.") public ResponseEntity> getSoupList() { List dishes = dishService.getList(1); return ResponseEntity.ok().body(dishes); diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java index 931e84802..cdf6378dc 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/domain/CategoryMockRepository.java @@ -5,9 +5,9 @@ public class CategoryMockRepository implements CategoryRepository { private final List categories = Arrays.asList( - new Category(1, "메인", "/main"), - new Category(2, "국", "/soup"), - new Category(3, "반찬", "/side") + new Category(1, "모두가 좋아하는 든든한 메인요리", "/main"), + new Category(2, "뜨끈하고 시원한 국물요리", "/soup"), + new Category(3, "밥도둑이 여기있다! 반찬요리", "/side") ); @Override From a30fe0658e2ae673f8412c5a7a5981b3c648081f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=A9=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=AA=E1=86=AB=20=28Can=29?= Date: Thu, 22 Apr 2021 11:06:02 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[chore]=20DB=20=EC=97=B0=EB=8F=99=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=EB=A1=9C=20=EB=AC=B4=ED=9A=A8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sidedish/SideDish/SideDishApplication.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/com/codesquad/sidedish/SideDish/SideDishApplication.java b/backend/src/main/java/com/codesquad/sidedish/SideDish/SideDishApplication.java index 34d203634..60bdbe314 100644 --- a/backend/src/main/java/com/codesquad/sidedish/SideDish/SideDishApplication.java +++ b/backend/src/main/java/com/codesquad/sidedish/SideDish/SideDishApplication.java @@ -2,12 +2,19 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -@SpringBootApplication +// FIXME: DB 연동을 무효화하기 위해서 임시로 exclude 함, 나중에 수정할 예정 +@SpringBootApplication(exclude = { + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class}) public class SideDishApplication { - public static void main(String[] args) { - SpringApplication.run(SideDishApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SideDishApplication.class, args); + } } From 214a26a115422c18a650d39eef3e7fb52db54534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=A9=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=AA=E1=86=AB=20=28Can=29?= Date: Thu, 22 Apr 2021 14:30:30 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[docs]=20README=20=EC=97=90=20API=20?= =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EB=A7=81=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/README.md b/backend/README.md index 60f316223..a70de8974 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,3 +1,7 @@ # Backend 백엔드를 위한 디렉토리 + +## API 배포 링크 + +http://3.37.26.82:8080/swagger-ui.html