-
Notifications
You must be signed in to change notification settings - Fork 3
[#26] 장바구니 도메인 추가 #44
base: feature/39
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package me.jjeda.mall.cart.configs; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; | ||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; | ||
import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
|
||
@Configuration | ||
@EnableRedisRepositories | ||
public class RedisConfig { | ||
@Value("${spring.redis.host}") | ||
private String redisHost; | ||
|
||
@Value("${spring.redis.port}") | ||
private int redisPort; | ||
|
||
@Bean | ||
public RedisConnectionFactory redisConnectionFactory() { | ||
return new LettuceConnectionFactory(redisHost, redisPort); | ||
} | ||
|
||
@Bean | ||
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory, ObjectMapper objectMapper) { | ||
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper); | ||
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>(); | ||
|
||
redisTemplate.setConnectionFactory(redisConnectionFactory); | ||
redisTemplate.setKeySerializer(new StringRedisSerializer()); | ||
redisTemplate.setValueSerializer(serializer); | ||
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); | ||
redisTemplate.setHashValueSerializer(serializer); | ||
|
||
return redisTemplate; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package me.jjeda.mall.cart.controller; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import me.jjeda.mall.accounts.dto.AccountDto; | ||
import me.jjeda.mall.cart.domain.CartItem; | ||
import me.jjeda.mall.cart.domain.CartModifyType; | ||
import me.jjeda.mall.cart.service.CartService; | ||
import me.jjeda.mall.common.CurrentUser; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.PutMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
|
||
import java.util.Objects; | ||
|
||
@Controller | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/carts") | ||
public class CartController { | ||
private final CartService cartService; | ||
|
||
@GetMapping | ||
public ResponseEntity getCart(@CurrentUser AccountDto accountDto) { | ||
return ResponseEntity.ok(cartService.getCart(String.valueOf(accountDto.getEmail()))); | ||
} | ||
|
||
@PutMapping | ||
public ResponseEntity modifyCart(@CurrentUser AccountDto accountDto, @RequestBody CartItem cartItem, | ||
@RequestParam CartModifyType cartModifyType) { | ||
|
||
if(Objects.equals(cartModifyType,CartModifyType.ADD)) { | ||
return ResponseEntity.ok(cartService.addItem(String.valueOf(accountDto.getEmail()), cartItem)); | ||
} else { | ||
return ResponseEntity.ok(cartService.removeItem(String.valueOf(accountDto.getEmail()), cartItem)); | ||
} | ||
} | ||
@DeleteMapping | ||
public ResponseEntity deleteCart(@CurrentUser AccountDto accountDto) { | ||
cartService.deleteCart(String.valueOf(accountDto.getId())); | ||
return ResponseEntity.ok().build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package me.jjeda.mall.cart.domain; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.redis.core.RedisHash; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Getter | ||
@Builder | ||
@RedisHash("cart") | ||
@NoArgsConstructor(access = AccessLevel.PACKAGE) | ||
@AllArgsConstructor(access = AccessLevel.PACKAGE) | ||
public class Cart { | ||
|
||
@Id | ||
private String id; | ||
|
||
private List<CartItem> cartItemList; | ||
|
||
private Cart(String id) { | ||
this.id = id; | ||
this.cartItemList = new ArrayList<>(); | ||
} | ||
|
||
public static Cart of(String id) { | ||
return new Cart(id); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package me.jjeda.mall.cart.domain; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import me.jjeda.mall.items.domain.Item; | ||
|
||
@Getter | ||
@EqualsAndHashCode | ||
@Builder | ||
@AllArgsConstructor(access = AccessLevel.PACKAGE) | ||
public class CartItem { | ||
private Item item; | ||
private int price; | ||
private int quantity; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package me.jjeda.mall.cart.domain; | ||
|
||
public enum CartModifyType { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요청의 내용을 TYPE으로 분기하게 되면 API의 설계가 잘못됐을 가능성도 생각해볼 수 있습니다. 위의 리뷰를 참고하셔서 수정해보시면 좋을 것 같습니다~ |
||
ADD, REMOVE | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package me.jjeda.mall.cart.repository; | ||
|
||
import me.jjeda.mall.cart.domain.Cart; | ||
import org.springframework.data.repository.CrudRepository; | ||
|
||
public interface CartRedisRepository extends CrudRepository<Cart, String> { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package me.jjeda.mall.cart.service; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import me.jjeda.mall.cart.domain.Cart; | ||
import me.jjeda.mall.cart.domain.CartItem; | ||
import me.jjeda.mall.cart.repository.CartRedisRepository; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import javax.persistence.EntityNotFoundException; | ||
import java.util.List; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class CartService { | ||
private final CartRedisRepository cartRedisRepository; | ||
|
||
@Transactional(readOnly = true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SQL이 1개만 나가게되는데 트랜잭션을 걸어준 이유가 있을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 트랜잭션에 대한 이해가 부족했네요..ㅎㅎ |
||
public Cart getCart(String id) { | ||
return cartRedisRepository.findById(id).orElseThrow(EntityNotFoundException::new); | ||
} | ||
|
||
@Transactional | ||
public Cart addItem(String id, CartItem cartItem) { | ||
final Cart cart; | ||
|
||
if (!cartRedisRepository.existsById(id)) { | ||
cart = Cart.of(id); | ||
} else { | ||
cart = getCart(id); | ||
} | ||
|
||
List<CartItem> cartItemList = cart.getCartItemList(); | ||
cartItemList.add(cartItem); | ||
return cartRedisRepository.save(cart); | ||
} | ||
|
||
@Transactional | ||
public Cart removeItem(String id, CartItem cartItem) { | ||
final Cart cart = getCart(id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. final을 걸어주는건 괜찮지만 이 변수에만 걸어준 이유가 있을까요? 컨벤션은 일관적이면 좋을 것 같아서요~ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
List<CartItem> cartItemList = cart.getCartItemList(); | ||
cartItemList.remove(cartItem); | ||
|
||
return cartRedisRepository.save(cart); | ||
} | ||
|
||
@Transactional | ||
public void deleteCart(String id) { | ||
cartRedisRepository.delete(getCart(id)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
spring.redis.port=6379 | ||
spring.redis.host=localhost | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런식으로 나누기보다는
/carts/items
이런식의 도메인구조면 더 역할나누기가 수월할 것 같습니다~