Skip to content

Commit

Permalink
메시지버스 형식으로 리팩터링
Browse files Browse the repository at this point in the history
  • Loading branch information
riroan committed Aug 24, 2024
1 parent 61f0220 commit b33edad
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 101 deletions.
2 changes: 2 additions & 0 deletions command/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Command:
pass
20 changes: 20 additions & 0 deletions command/cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from dataclasses import dataclass

from command import Command


@dataclass(frozen=True)
class AddCartCommand(Command):
user_id: int
product_id: int


@dataclass(frozen=True)
class UpdateCartCommand(Command):
cart_id: int
count: int


@dataclass(frozen=True)
class DeleteCartCommand(Command):
cart_id: int
15 changes: 15 additions & 0 deletions command/like.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from dataclasses import dataclass

from command import Command


@dataclass(frozen=True)
class LikeCommand(Command):
user_id: int
product_id: int


@dataclass(frozen=True)
class DislikeCommand(Command):
user_id: int
product_id: int
11 changes: 11 additions & 0 deletions command/product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from dataclasses import dataclass

from command import Command


@dataclass(frozen=True)
class AddProductCommand(Command):
name: str
image_path: str
price: int
summary: str | None
8 changes: 8 additions & 0 deletions depends.py → depends/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from typing import Annotated

from fastapi import Depends, Request
from sqlalchemy.orm.session import Session

from db import Database
from messagebus import MessageBus
from settings import Settings


Expand All @@ -26,3 +28,9 @@ async def get_session(
except Exception as e:
session.rollback()
raise e


async def get_messagebus(
session: Annotated[Session, Depends(get_session)]
):
return MessageBus(session)
22 changes: 22 additions & 0 deletions depends/cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from command.cart import AddCartCommand, DeleteCartCommand, UpdateCartCommand
from dto.cart import CartDto, CartUpdateDto


async def add_cart_command(cart: CartDto):
return AddCartCommand(
user_id=cart.user_id,
product_id=cart.product_id
)


async def update_cart_command(cart: CartUpdateDto, cart_id: int):
return UpdateCartCommand(
cart_id=cart_id,
count=cart.count
)


async def delete_cart_command(cart_id: int):
return DeleteCartCommand(
cart_id=cart_id
)
16 changes: 16 additions & 0 deletions depends/like.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from command.like import DislikeCommand, LikeCommand
from dto.like import LikeDto


async def like_command(like_data: LikeDto):
return LikeCommand(
user_id=like_data.user_id,
product_id=like_data.product_id
)


async def dislike_command(like_data: LikeDto):
return DislikeCommand(
user_id=like_data.user_id,
product_id=like_data.product_id
)
11 changes: 11 additions & 0 deletions depends/product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from command.product import AddProductCommand
from dto.product import ProductDto


async def add_product_command(product: ProductDto):
return AddProductCommand(
name=product.name,
image_path=product.image_path,
price=product.price,
summary=product.summary
)
41 changes: 41 additions & 0 deletions messagebus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from collections import deque

from sqlalchemy.orm.session import Session

from command import Command
from command.cart import AddCartCommand, DeleteCartCommand, UpdateCartCommand
from command.like import DislikeCommand, LikeCommand
from command.product import AddProductCommand
from service.cart import add_cart, delete_cart, update_cart
from service.like import dislike, like
from service.product import add_product

Message = Command


class MessageBus:
def __init__(self, session: Session):
self.session = session
self.message_queue = None
self.command_handlers = COMMAND_HANDLERS

async def handle(self, message: Message):
self.message_queue = deque([message])
while self.message_queue:
target = self.message_queue.popleft()
ret = await self.handle_command(target)
return ret

async def handle_command(self, command: Command):
handler = self.command_handlers[type(command)]
return await handler(command, self.session)


COMMAND_HANDLERS = {
AddCartCommand: add_cart,
UpdateCartCommand: update_cart,
DeleteCartCommand: delete_cart,
LikeCommand: like,
DislikeCommand: dislike,
AddProductCommand: add_product,
}
46 changes: 22 additions & 24 deletions presentation/cart.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@
from fastapi import APIRouter, Depends, status
from sqlalchemy.orm.session import Session

from depends import get_session
from dto.cart import CartDto, CartResponseDto, CartResponseModel, CartUpdateDto
from command.cart import AddCartCommand, DeleteCartCommand, UpdateCartCommand
from depends import get_messagebus, get_session
from depends.cart import (add_cart_command, delete_cart_command,
update_cart_command)
from dto.cart import CartResponseDto, CartResponseModel
from messagebus import MessageBus
from service import cart as cart_service

api = APIRouter()


@api.get("/{user_id}", status_code=status.HTTP_200_OK)
async def list_shoppingcart(
async def list_cart(
user_id: int,
session: Annotated[Session, Depends(get_session)]
) -> CartResponseModel:
cart_products = await cart_service.list_shoppingcart(
cart_products = await cart_service.list_cart(
user_id, session
)

Expand All @@ -30,30 +34,24 @@ async def list_shoppingcart(


@api.post("", status_code=status.HTTP_201_CREATED)
async def add_shoppingcart(
cart: CartDto,
session: Annotated[Session, Depends(get_session)]
) -> CartDto:
await cart_service.add_shoppingcart(cart, session)
return cart
async def add_cart(
command: Annotated[AddCartCommand, Depends(add_cart_command)],
messagebus: Annotated[MessageBus, Depends(get_messagebus)]
):
return await messagebus.handle(command)


@api.put("/{cart_id}", status_code=status.HTTP_202_ACCEPTED)
async def update_shoppingcart(
cart_id: int,
cart: CartUpdateDto,
session: Annotated[Session, Depends(get_session)]
) -> CartUpdateDto:
await cart_service.update_shoppingcart(cart_id, cart, session)

return cart
async def update_cart(
command: Annotated[UpdateCartCommand, Depends(update_cart_command)],
messagebus: Annotated[MessageBus, Depends(get_messagebus)]
):
return await messagebus.handle(command)


@api.delete("/{cart_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_shoppingcart(
cart_id: int,
session: Annotated[Session, Depends(get_session)]
async def delete_cart(
command: Annotated[DeleteCartCommand, Depends(delete_cart_command)],
messagebus: Annotated[MessageBus, Depends(get_messagebus)]
) -> None:
await cart_service.delete_shoppingcart(
cart_id, session
)
await messagebus.handle(command)
28 changes: 12 additions & 16 deletions presentation/like.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
from typing import Annotated

from fastapi import APIRouter, Depends, status
from sqlalchemy.orm.session import Session

from depends import get_session
from dto.like import LikeDto
from service import like as like_service
from command.like import DislikeCommand, LikeCommand
from depends import get_messagebus
from depends.like import dislike_command, like_command
from messagebus import MessageBus

api = APIRouter()


@api.post("/like", status_code=status.HTTP_201_CREATED)
async def like(
like_data: LikeDto,
session: Annotated[Session, Depends(get_session)]
) -> LikeDto:
await like_service.like(like_data, session)

return like_data
command: Annotated[LikeCommand, Depends(like_command)],
messagebus: Annotated[MessageBus, Depends(get_messagebus)]
):
return await messagebus.handle(command)


@api.post("/dislike", status_code=status.HTTP_201_CREATED)
async def dislike(
like_data: LikeDto,
session: Annotated[Session, Depends(get_session)]
) -> LikeDto:
await like_service.dislike(like_data, session)

return like_data
command: Annotated[DislikeCommand, Depends(dislike_command)],
messagebus: Annotated[MessageBus, Depends(get_messagebus)]
):
return await messagebus.handle(command)
18 changes: 9 additions & 9 deletions presentation/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
from fastapi import APIRouter, Depends, status
from sqlalchemy.orm.session import Session

from depends import get_session
from dto.product import ProductDto, ProductResponseDto, ProductResponseModel
from command.product import AddProductCommand
from depends import get_messagebus, get_session
from depends.product import add_product_command
from dto.product import ProductResponseDto, ProductResponseModel
from messagebus import MessageBus
from service import product as product_service

api = APIRouter()
Expand Down Expand Up @@ -37,10 +40,7 @@ async def list_product(

@api.post("", status_code=status.HTTP_201_CREATED)
async def add_product(
product: ProductDto,
session: Annotated[Session, Depends(get_session)]
) -> ProductDto:
await product_service.add_product(
product, session
)
return product
command: Annotated[AddProductCommand, Depends(add_product_command)],
messagebus: Annotated[MessageBus, Depends(get_messagebus)]
):
return await messagebus.handle(command)
Loading

0 comments on commit b33edad

Please sign in to comment.