- 회원 서비스 구현 완료
- 카카오 로그인 djangorestframework-simplejwt 이용하여 액세스 토큰 관리
- 배송 서비스 구현 완료
- docker-compose (django, rabbitmq, celery)
- 배송 출발 ➡ Rabbitmq(broker) + Celery(worker) 비동기 300초 지연 시간 ➡ 배송 도착
- 아이템 서비스 구현 완료
- 주문 서비스 구현 완료
- django==4.2.11
# stable version
- djangorestframework
- djangorestframework-simplejwt
- drf-yasg
- Django
- rabbitmq
- celery
- GET /health/
# ok
1. UserModel Kakao signin, signup
2. docker-compose (django, rabbitmq, celery)
3. I used Swagger(drf-yasg)
4. simplejwt using bearer JWT token
5. TestCode
- [POST] accounts/signup
- [POST] accounts/signin
- [POST] accounts/token/verify
- [POST] accounts/token/refresh
- [GET] /deliveries/ list
- [POST] /deliveries/ create
- [GET] /deliveries/{id}/ read
- [PUT] /deliveries/{id}/ update
- [PATCH] /deliveries/{id}/ partial update
- [DELETE] /deliveries/{id}/ delete
- [GET] /deliveries/{id}/departure departure ➡ arrival
- [GET] /deliveries/ list
- [POST] /deliveries/ create
- [GET] /deliveries/{id}/ read
- [PUT] /deliveries/{id}/ update
- [PATCH] /deliveries/{id}/ partial update
- [DELETE] /deliveries/{id}/ delete
- [GET] /deliveries/ list
- [POST] /deliveries/ create
- [GET] /deliveries/{id}/ read
- [PUT] /deliveries/{id}/ update
- [PATCH] /deliveries/{id}/ partial update
- [DELETE] /deliveries/{id}/ delete
- 딕셔너리 컴프리헨션
class OrderSerializer(serializers.ModelSerializer):
items_details = serializers.SerializerMethodField()
class Meta:
model = Order
fields = ['user', 'items_details']
def get_items_details(self, obj):
return {item.id: item.name for item in obj.items.all()}
- get_random_string 랜덤 문자열
from django.utils.crypto import get_random_string
target = get_random_string(length=16, allowed_chars="가나다라마바사thankyousomuch")
- Swagger details
access_token = openapi.Parameter('access_token', openapi.IN_QUERY, description="Send it to me from Frontend", required=True, type=openapi.TYPE_STRING)
@swagger_auto_schema(operation_description="프론트엔드(POSTMAN) 토큰 전달", responses={200: 'Success'}, manual_parameters=[access_token])
- custom middleware
from django.http import JsonResponse
class HealthCheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path == '/health/' or request.path == '/health':
return JsonResponse({"status": "ok"}, status=200)
return self.get_response(request)
- Celery all flow
# config/settings.py
INSTALLED_APPS = ['celery',]
CELERY_TIMEZONE = TIME_ZONE
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60
# CELERY_BROKER_URL = os.environ.get("CELERY_BROKER", "redis://redis:6379/0")
# CELERY_RESULT_BACKEND = os.environ.get("CELERY_BACKEND", "redis://redis:6379/0")
CELERY_BROKER_URL="amqp://guest:guest@rabbitmq:5672//"
# CELERY_RESULT_BACKEND = 'django-db'
# config/celery.py
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery("config")
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
# config/__init__.py
from .celery import app as celery_app
__all__ = ['celery_app']
# app/tasks.py
from config.celery import app
from .models import Delivery
@app.task
def process_delivery_task(delivery_id):
instance = Delivery.objects.get(id=delivery_id)
instance.status = "2" # 배송 완료
instance.save()
# app/views.py
class DeliveryViewSet(viewsets.ModelViewSet):
queryset = Delivery.objects.all()
serializer_class = DeliverySerializer
permission_classes = [permissions.IsAuthenticated]
authentication_classes = [JWTAuthentication]
@action(detail=True, methods=['GET'], name='departure')
def departure(self, request, pk=None):
instance = self.get_object()
if instance.status == '2':
return JsonResponse({'message': f'{instance.receiver.kakao_id} 고객님의 상품은 이미 배송이 완료 되었습니다.'})
instance.status = '1'
instance.save()
process_delivery_task.s(delivery_id=instance.id).apply_async(countdown=60)
return JsonResponse({'message': f'{instance.receiver.kakao_id} 고객님의 상품 {instance.order.item.name} 배송이 출발하였습니다. the delivery service will arrive in 60 seconds'})
- Postman - Authorization Client ID, Callback URL, ... 설정 후 -
Get New Access Token
- 카카오 로그인창 - 회원가입/로그인 -
카카오 토큰 발급
- 카카오 토큰으로
회원정보 확인 가능
- 카카오 토큰으로
회원가입/로그인
토큰 발급 access_token - access_token 으로 shipment 서비스 이용 가능
- Swagger - Authorize - Bearer eyJhbGciOiJIUzI1NiIsI...
- 토큰과 함께 판매할 아이템을 생성
{
"id": 2,
"user": 1,
"name": "반포자이",
"description": "",
"price": 20000000000
}
- 토큰으로 다른 사용자도 판매 등록한 아이템 조회
[
{
"id": 1,
"user": 2,
"name": "리더스빌",
"description": "",
"price": 175000000
},
{
"id": 2,
"user": 1,
"name": "반포자이",
"description": "",
"price": 20000000000
}
]
- 상대방의 아이템 ID 를 입력
{
"user":2,
"item":1,
"purchase_date":"2024-12-04T12:47:40.641913Z"
}
- 토큰으로 API 를 이용하는 사람은 판매자
- order 정보에 판매자, 구매자 정보가 존재
{
"order": 1,
"address": "서초구 반포동",
"status": "0" // pending
}
// response
{
"id": 3,
"order": 1,
"sender": 1,
"receiver": 2,
"address": "서초구 반동",
"status": "0"
}
- Delivery ID 입력
{
"id": 3
}
// response
{
"message": "3408007879 고객님의 상품 반포자이 배송이 출발하였습니다. the delivery service will arrive in 60 seconds"
}