[ํด๋ก ์ฝ๋ฉ] ์ปคํผ๋น ์ฃผ๋ฌธ ๊ด๋ฆฌ ์๋น์ค
0. ์๊ตฌ์ฌํญ
- ๋งค์ผ ์ ๋ ์คํ 2์๋ถํฐ ์ค๋ ์ค๋ฃจ 2์๊น์ง์ ์ฃผ๋ฌธ์ ๋ชจ์์ ์ฒ๋ฆฌ
- ํ์ฌ ์ด 4๊ฐ์ ์ํ ์กด์ฌ
- ๋ณ๋์ ํ์์ ๊ด๋ฆฌํ์ง ์๊ณ , email๋ก ๊ตฌ๋ถ
- ํ๋ฃจ์ ๊ฐ์ email๋ก ์ฌ๋ฌ๋ฒ ์ฃผ๋ฌธ์ด ๋ค์ด์ฌ ๊ฒฝ์ฐ ํ๋๋ก ํฉ์ณ์ ๋ค์๋ ๋ฐฐ์ก
- ๊ณ ๊ฐ์๊ฐ “๋น์ผ ์คํ 2์ ์ดํ์ ์ฃผ๋ฌธ์ ๋ค์๋ ๋ฐฐ์ก์ ์์ํฉ๋๋ค.”๋ผ๊ณ ์๋ ค์ค๋๋ค.
1. ํ๋ก์ ํธ ์์ฑ
2. domain ๋ชจ๋ธ ์ ์
→ ์ํ ๋๋ฉ์ธ
→ ์ฃผ๋ฌธ ๋๋ฉ์ธ
- validation Object ๋ง๋ค๊ธฐ
public class Email {
private final String address;
public Email(String address) {
Assert.notNull(address);
Assert.isTrue(address.length() >= 4 && address.length() <= 50,"address length must be between 4 and 50 characters");
Assert.isTrue(checkAddress(address), "Invalid email address");
this.address = address;
}
private boolean checkAddress(String address) {
return Pattern.matches("\\\\b[\\\\w\\\\.-]+@[\\\\w\\\\.-]+\\\\.\\\\w{2,4}\\\\b",address);
}
//validation ํ ๋, equals๋ hashcode๋ฅผ ์ง์ ๊ตฌํํด ์ฃผ๋ ๊ฒ์ด ์ข๋ค.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Email email = (Email) o;
return Objects.equals(address, email.address);
}
@Override
public int hashCode() {
return Objects.hash(address);
}
@Override
public String toString() {
return "Email{" +
"address='" + address + '\\'' +
'}';
}
public String getAddress() {
return address;
}
}
์ ๊ท ๋ถํฌ์ ๊ตฌํ๊ธฐ → https://regexr.com/
RegExr: Learn, Build, & Test RegEx
RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).
regexr.com
3. repository ๊ตฌํ, test ์ฝ๋ ์์ฑ
@Repository
public class OrderJdbcRepository implements OrderRepository {
private final NamedParameterJdbcTemplate jdbcTemplate;
public OrderJdbcRepository(NamedParameterJdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
@Transactional
public Order insert(Order order) {
jdbcTemplate.update("INSERT INTO orders(order_id, email, address, postcode, order_status, create_at, update_at) " +
"VALUES (UUID_TO_BIN(:orderId), :email, :address, :postcode, :orderStatus, :createAt, :updateAt)",
toOrderParamMap(order));
order.getOrderItems()
.forEach(item ->
jdbcTemplate.update("INSERT INTO order_item(order_id, product_id, category, price, quantity, create_at, update_at) " +
"VALUES (UUID_TO_BIN(:orderId), UUID_TO_BIN(:productId), :category, :price, :quantity, :createAt, :updateAt)",
toOrderItemParamMap(order.getOrderId(), order.getCreatedAt(), order.getUpdateAt(), item)));
return order;
}
private Map<String, Object> toOrderParamMap(Order order) {
var paramMap = new HashMap<String, Object>();
paramMap.put("orderId", order.getOrderId().toString().getBytes());
paramMap.put("email", order.getEmail().getAddress());
paramMap.put("address", order.getAddress());
paramMap.put("postcode", order.getPostcode());
paramMap.put("orderStatus", order.getOrderStatus().toString());
paramMap.put("createAt", order.getCreatedAt());
paramMap.put("updateAt", order.getUpdateAt());
return paramMap;
}
private Map<String, Object> toOrderItemParamMap(UUID orderId, LocalDateTime createdAt, LocalDateTime updatedAt, OrderItem item) {
var paramMap = new HashMap<String, Object>();
paramMap.put("orderId", orderId.toString().getBytes());
paramMap.put("productId", item.productId().toString().getBytes());
paramMap.put("category", item.category().toString());
paramMap.put("price", item.price());
paramMap.put("quantity", item.quantity());
paramMap.put("createAt", createdAt);
paramMap.put("updateAt", updatedAt);
return paramMap;
}
}
Map ์ด๊ธฐํ์ ์ฃผ์ ์ฌํญ
1. ์ด์ค ์ค๊ดํ๋ฅผ ์ฌ์ฉํ ์ด๊ธฐํ ์ง์
https://www.baeldung.com/java-double-brace-initialization
2. ํฉํ ๋ฆฌ ๋ฉ์๋(map.of)๋ฅผ ์ฌ์ฉํ ์ด๊ธฐํ์ ๋ฌธ์ -> nullableํ ๊ฐ์ด ๋ค์ด์ฌ๋ map์ด null๊ฐ์ ๋ํ error๋ฅผ ๋ฐ์์ํจ๋ค.
=> ๋ฌด๋ํ๊ฒ HashMap์ ์ด์ฉํด ์ด๊ธฐํ๋ฅผ ํ์
4. service ๊ตฌํ
@Service
public class DefaultOrderService implements OrderService {
private final OrderRepository orderRepository;
public DefaultOrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public Order createOrder(Email email, String address, String postcode, List<OrderItem> orderItems) {
Order order = new Order(
UUID.randomUUID(),
email,
address,
postcode,
orderItems,
OrderStatus.ACCEPTED,
LocalDateTime.now(),
LocalDateTime.now());
return orderRepository.insert(order);
}
}
5. controller ๊ตฌํ
REST API ๋ฅผ ๋ง๋ ๋ controller๊ฐ ์๋๋ผ ์นํ์ด์ง์ ์ ์ํ๊ธฐ์ํ view๋ฅผ ๋ฐํํด์ฃผ๋ controller
controller๋ ์ธ๋ถ๋ก ๋ถํฐ DTO๋ก ๋ฐ์์ Validation์ด๋, http ํธ๋ค์ ์ํํ๋ค. ๋๋ฉ์ธ ๋ก์ง์ Service์ entity์์!
@Controller
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping("/products")
public String productsPage(Model model){
var products = productService.getAllProducts();
model.addAttribute("products",products);
return "product-list";
}
@GetMapping("new-product")
public String newProductPage(Model model){
return "new-product";
}
@PostMapping("/products")
public String newProduct(CreateProductRequest createProductRequest){
productService.createProduct(createProductRequest.productName(),createProductRequest.category(),
createProductRequest.price(),createProductRequest.description());
return "redirect:/products";
}
}
6. template ์์ฑ
- new-product.html
- product-list.html
7. React ์ฝ๋ ์์ฑ
: axios ์ฌ์ฉ
8 . API
- CORS ์ค์
@Configuration
public class MvcConfiguration implements WebMvcConfigurer { // mvc ์ค์ ํ์ฅ
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**").allowedOrigins("*");
}
}
- ์ฃผ๋ฌธ ์ฒ๋ฆฌ API ๊ตฌํ
@RestController
public class OrderRestController {
private final OrderService orderService;
public OrderRestController(OrderService orderService) {
this.orderService = orderService;
}
@PostMapping("/api/v1/orders")
public Order createOrder(@RequestBody CreateOrderRequest createOrderRequest){
return orderService.createOrder(
new Email(createOrderRequest.email()),
createOrderRequest.address(),
createOrderRequest.postcode(),
createOrderRequest.orderItems()
);
}
}
- CreateOrderRequest -> json์ ํํํ๊ธฐ ์ํ ํ์ ์ ์ ์ํ ์ ์๋ค. (DTO๋ฅผ messageํฌ๋งท์ผ๋ก ๋ณ๊ฒฝ์ํค๊ธฐ ์ํ ์ ์ํ ์ ์๋ค.)
- service์์ ์ธ์งํ๋ ๊ฒ๋ณด๋ค. service๋ service ์์ฒด์ ๋ฉ์ธ์ง ์๊ทธ๋์ณ๋ฅผ ๊ฐ์ ธ๊ฐ๊ณ controller๊ฐ service๊ฐ ํ์ํ value Object๋ parameter์ ๋ณ์๋ก ๋ณํํ๋๋ก ๋์ผํ ๊ฐ์ ๋๊ฒจ ์ค์ง๋ผ๊ณ ๊ณ์ธต์ ๊ตฌ๋ถํ๋ ๊ฒ์ด ์ข๋ค.
์์ค์ฝ๋
https://github.com/youngjijang/prgrms-be-devcourse
GitHub - youngjijang/prgrms-be-devcourse: ํ๋ก๊ทธ๋๋จธ์ค ๋ฐ๋ธ์ฝ์ค ๋ฐฑ์๋ ์ค์ต repo
ํ๋ก๊ทธ๋๋จธ์ค ๋ฐ๋ธ์ฝ์ค ๋ฐฑ์๋ ์ค์ต repo. Contribute to youngjijang/prgrms-be-devcourse development by creating an account on GitHub.
github.com
'Back-end ๋ฐ๋ธ์ฝ์ค > week 06 - 07 TIL (clone project)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] 221202 - A to Z ํ๋ก์ ํธ ๊ณผ์ (0) | 2022.12.07 |
---|---|
[TIL] 221124 - SpringBoot Part2 ๊ณผ์ ๋ฅผ ์งํํ๋ฉฐ (๊ฐ์ฒด์งํฅ์ ์ธ DB ์ค๊ณ) (0) | 2022.11.26 |
๋๊ธ