Published on

[django] apig-wsgi 사용법

Authors
  • avatar
    Name
    Almer Minified
    Twitter

장고를 서버리스로 배포하는 방법

AWS Lambda에서 Django 애플리케이션을 호스팅하려면 몇 가지 고려해야 할 사항이 있다. 일반적으로 Zappa를 사용하는데 Zappa는 AWS Lambda에 Django를 배포하는 데 주로 사용된다. 이 도구에 대한 자세한 정보는 Zappa의 GitHub 페이지에서 확인할 수 있다.

Zappa 본 홈페이지

그러나 Zappa 사용에는 몇 가지 제한 사항이 있다.

첫째, Zappa는 AWS CloudFormation을 이용한다.

둘째, Zappa는 패키징에서부터 배포까지의 과정을 세밀하게 조절하기 어렵다.

Zappa는 'package' 명령어를 제공하지만 이는 Zappa에 종속된 명령어이므로 사용자가 마음대로 조절하기 어렵다.

세번째, 의존성 관리도 별도로 해야 한다.

AWS Lambda에서 Django나 Flask와 같은 WSGI 애플리케이션을 운영하려면 handler 설정이 필요하다. 이를 단순화해주는 라이브러리는 많지 않다. Zappa는 큰 생태계를 가지고 있지만 Django나 Flask를 Lambda에 직접 올리는 것은 자파에서 제대로 지원해주지 않거나 사용하기 위해서도 많은 고려사항을 따져야 한다.

APIG

이런 상황에서 'apig-wsgi' 라이브러리를 사용하는 것이 좋다.

apig-wsgi pypi 페이지

라이브러리는 WSGI 애플리케이션을 AWS Lambda에서 실행할 수 있도록 변환해준다. 'apig-wsgi'는 바이너리 응답을 지원하고 이를 활성화하거나 비활성화할 수 있다. Django와 같은 웹 서버에서 바이너리 데이터를 사용할 때 발생하는 비용을 고려해서 필요에 따라 이 기능을 비활성화할 수 있다.

'apig-wsgi'를 사용하면 AWS API Gateway에서 오는 이벤트의 특정 키를 WSGI 환경에서 사용할 수 있다. 예를 들어 requestContext 키가 있는 경우 WSGI 환경에서 environ['apig_wsgi.request_context']를 사용하여 이를 활용할 수 있다. 또한 다수의 헤더 값을 활성화할 경우 이를 확인하기 위한 키도 제공한다.

실전 예제

Django의 wsgi.py 파일에 apig_wsgi를 적용해보자

import os
import json
from django.core.wsgi import get_wsgi_application
from apig_wsgi import make_lambda_handler

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sample-project.settings')

# WSGI 애플리케이션 설정

django_app = get_wsgi_application()
lambda_ready_handler = make_lambda_handler(django_app, binary_support=True)

def custom_lambda_handler(event, context):
print(json.dumps(event, indent=2, sort_keys=True))
response = lambda_ready_handler(event, context)
return response

위 코드에서 custom_lambda_handler는 AWS Lambda에서 지정할 수 있는 핸들러 함수다.

이를 통해 Django 애플리케이션을 AWS Lambda에서 효율적으로 운영할 수 있다.

REST 구조 만들기

AWS Lambda와 ALB를 사용하여 Django 기반의 RESTful API를 구현하는 경우 apig-wsgi를 사용하는 것이 효과적인 방법이 될 수 있다. 여기서는 Django를 활용하여 RESTful API를 만들고 apig-wsgi를 사용하여 이를 AWS Lambda에서 호스팅해보자.

apig-wsgi와 Django를 이용한 RESTful API 구현

파라미터 처리

기존 장고의 뷰를 통해 쉽게 관리할 수 있다.

ALB 엔드포인트와 Lambda 연결

AWS Lambda를 사용할 때 ALB 엔드포인트를 Lambda 함수에 연결한다. apig-wsgi는 Lambda 이벤트를 WSGI 요청으로 변환해서 Django 애플리케이션과 호환되게 한다.

예시

# Django views.py

from django.http import JsonResponse

def health_check(request, health_param): # 간단한 헬스 체크 뷰
return JsonResponse({"health": health_param})

def create_post(request):
if request.method == "POST": # POST 요청 처리
data = request.POST # 여기서 데이터 처리 및 저장
return JsonResponse({"result": "success"})
return JsonResponse({"error": "Invalid request"}, status=400)

기존 django의 views를 쓰듯 쓰면 된다.

# Django urls.py 예시

from django.urls import path
from .views import health_check, create_post

urlpatterns = [
path('internal/<str:health_param>/', health_check),
path('create_post/', create_post),
]

이것도 크게 달라진 점은 없다.

# apig-wsgi와 함께 사용하는 Lambda 함수

from django.core.wsgi import get_wsgi_application
from apig_wsgi import make_lambda_handler

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sample_project.settings')
django_app = get_wsgi_application()
lambda_handler = make_lambda_handler(django_app, binary_support=True)

이 코드는 Django의 뷰와 URL 패턴을 사용하여 경로 및 POST 요청의 파라미터를 처리한다. 물론 배포시에 apig-wsgi 라이브러리를 통해 이를 AWS Lambda와 호환되게하는 것이 이번 실습의 요지였다. 이렇게 하면 Django 애플리케이션을 Lambda에서 RESTful API로 운영할 수 있다.