Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

[#26] 장바구니 도메인 추가 #44

Open
wants to merge 6 commits into
base: feature/39
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/main/java/me/jjeda/mall/cart/configs/RedisConfig.java
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;
}
}
48 changes: 48 additions & 0 deletions src/main/java/me/jjeda/mall/cart/controller/CartController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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.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;

@Controller
@RequiredArgsConstructor
@RequestMapping("/api/carts")
public class CartController {
private final CartService cartService;

@PostMapping
public ResponseEntity initCart(@CurrentUser AccountDto accountDto) {
return ResponseEntity.ok(cartService.initCart(String.valueOf(accountDto.getEmail())));
}

@GetMapping
public ResponseEntity getCart(@CurrentUser AccountDto accountDto) {
return ResponseEntity.ok(cartService.getCart(String.valueOf(accountDto.getEmail())));
}

@PutMapping("/add")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add, remove같은 의미들은 메소드에 담겨있으니 URL설계를 다시 해보시는것도 좋을 것 같습니다~

public ResponseEntity addItem(@CurrentUser AccountDto accountDto, @RequestBody CartItem cartItem) {
return ResponseEntity.ok(cartService.addItem(String.valueOf(accountDto.getEmail()), cartItem));
}

@PutMapping("/remove")
public ResponseEntity removeItem(@CurrentUser AccountDto accountDto, @RequestBody CartItem cartItem) {
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();
}
}
34 changes: 34 additions & 0 deletions src/main/java/me/jjeda/mall/cart/domain/Cart.java
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);
}
}
18 changes: 18 additions & 0 deletions src/main/java/me/jjeda/mall/cart/domain/CartItem.java
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,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> {
}
46 changes: 46 additions & 0 deletions src/main/java/me/jjeda/mall/cart/service/CartService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
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 javax.persistence.EntityNotFoundException;
import java.util.List;

@Service
@RequiredArgsConstructor
public class CartService {
private final CartRedisRepository cartRedisRepository;

public Cart initCart(String id) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 메소드는 addItem이랑 합쳐도 될것같습니다~

if (!cartRedisRepository.existsById(id)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거는 동시성문제가 생길 수 있겠네요. !cartRedisRepository.existsById(id)가 true라서 장바구니가 존재하지 않는다고 판단했는데 그 사이에 다른 스레드에서 save를 할 가능성이 있습니다~ (물론 한 계정의 장바구니에 대해 중복요청이 올 가능성은 거의 없지만요)

return cartRedisRepository.save(Cart.of(id));
}
return getCart(id);
}

public Cart getCart(String id) {
return cartRedisRepository.findById(id).orElseThrow(EntityNotFoundException::new);
}

public Cart addItem(String id, CartItem cartItem) {
Cart cart = getCart(id);
List<CartItem> cartItemList = cart.getCartItemList();
cartItemList.add(cartItem);
return cartRedisRepository.save(cart);
}

public Cart removeItem(String id, CartItem cartItem) {
Cart cart = getCart(id);
List<CartItem> cartItemList = cart.getCartItemList();
cartItemList.remove(cartItem);

return cartRedisRepository.save(cart);
}

public void deleteCart(String id) {
cartRedisRepository.delete(getCart(id));
}
}
2 changes: 2 additions & 0 deletions src/main/java/me/jjeda/mall/items/domain/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
Expand All @@ -22,6 +23,7 @@
@Entity
@Getter @Setter
@Builder
@EqualsAndHashCode
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Item {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
spring.redis.port=6379
spring.redis.host=localhost

Loading