Django REST Framework on Docker로 Hello World API 만들기

소개



Django REST Framework (DRF)를 사용하여 Docker 컨테이너에서 간단한 Hello World API를 만듭니다.
로컬을 더럽히지 않기 때문에, 코딩도 컨테이너상에서 가고 싶습니다.
몇 번이라도 다시 할 수있는 부담없는 개발 환경의 이미지입니다.

Django REST Framework란?



Python의 웹 애플리케이션 프레임 워크인 장고를 사용하여 API를 개발하는 데 사용되는 라이브러리입니다.
활용할 수 있으면 RESTful API 개발을 빨리 쉽게 (← 중요) 할 수 있습니다.
  • 공식 문서: 장고 REST Framework

  • 환경


  • Windows 10 Pro(20H2)
  • Docker Desktop: 3.1.0 (51484)
  • VSCode: 1.53.2

  • 0. 준비(필요하다면)



    컨테이너에서 코딩하기 위해 VSCode에 Remote - Containers 확장 프로그램을 설치합니다.


    1. Docker 이미지 빌드



    requirements.txt
    Django
    djangorestframework
    

    dockerfile
    FROM centos
    
    RUN yum -y groupinstall "development tools" \
    && yum -y install \
               wget \
               zlib-devel \
               openssl \
               openssl-devel \
               sqlite \
               sqlite-devel \
    && cd /opt \
    && wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz \
    && tar xzvf Python-3.9.2.tgz \
    && cd ./Python-3.9.2 \
    && ./configure --with-threads && make install && make clean \
    && rm -rf /opt/Python-3.9.2.tgz \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
    
    COPY ./requrements.txt /opt/
    RUN pip3 install --no-cache-dir -r /opt/requrements.txt
    

    ↑ 2개를 같은 계층에 두고, 그 디렉토리로 Docker 이미지를 빌드

    powershell
    PS C:\Users\sakimura\Documents\Programs> docker build . -t django_hello
    [+] Building 1.1s (9/9) FINISHED
     => [internal] load build definition from Dockerfile                                                               0.0s
     => => transferring dockerfile: 644B                                                                               0.0s
     => [internal] load .dockerignore                                                                                  0.0s
     => => transferring context: 2B                                                                                    0.0s
     => [internal] load metadata for docker.io/library/centos:latest                                                   0.0s
     => [1/5] FROM docker.io/library/centos                                                                            0.0s
     => [internal] load build context                                                                                  0.0s
     => => transferring context: 70B                                                                                   0.0s
     => CACHED [2/5] RUN yum -y groupinstall "development tools"                                                       0.0s
     => CACHED [3/5] RUN yum -y install            wget            zlib-devel            openssl            openssl-d  0.0s
     => [4/5] COPY ./requirements.txt /opt/                                                                            0.0s
     => ERROR [5/5] RUN pip3 install --no-cache-dir -r /opt/requrements.txt                                            0.9s
    ------
     > [5/5] RUN pip3 install --no-cache-dir -r /opt/requrements.txt:
    #9 0.637 ERROR: Could not open requirements file: [Errno 2] No such file or directory: '/opt/requrements.txt'
    #9 0.843 WARNING: You are using pip version 20.2.3; however, version 21.0.1 is available.
    #9 0.843 You should consider upgrading via the '/usr/local/bin/python3.9 -m pip install --upgrade pip' command.
    ------
    executor failed running [/bin/sh -c pip3 install --no-cache-dir -r /opt/requrements.txt]: exit code: 1
    PS C:\Users\sakimura\Documents\Programs> docker build . -t django_hello
    [+] Building 13.0s (10/10) FINISHED
     => [internal] load build definition from Dockerfile                                                               0.0s
     => => transferring dockerfile: 645B                                                                               0.0s
     => [internal] load .dockerignore                                                                                  0.0s
     => => transferring context: 2B                                                                                    0.0s
     => [internal] load metadata for docker.io/library/centos:latest                                                   0.0s
     => [1/5] FROM docker.io/library/centos                                                                            0.0s
     => [internal] load build context                                                                                  0.0s
     => => transferring context: 37B                                                                                   0.0s
     => CACHED [2/5] RUN yum -y groupinstall "development tools"                                                       0.0s
     => CACHED [3/5] RUN yum -y install            wget            zlib-devel            openssl            openssl-d  0.0s
     => CACHED [4/5] COPY ./requirements.txt /opt/                                                                     0.0s
     => [5/5] RUN pip3 install --no-cache-dir -r /opt/requirements.txt                                                12.1s
     => exporting to image                                                                                             0.8s
     => => exporting layers                                                                                            0.8s
     => => writing image sha256:adc1814ea2869e74515c44a91d91bb408c5af97a9d68309eea1368b3c0222130                       0.0s
     => => naming to docker.io/library/django_hello                                                                    0.0s
    

    프록시 환경의 경우 --build-arg http_proxy/https_proxy가 필요할 수 있습니다.
  • 참고 기사: 프록시 환경에서 docker image build하고 싶습니다.

  • 2. Docker 컨테이너 시작



    빌드한 이미지에서 컨테이너를 시작합니다.
    이번에는 컨테이너의 8000번 포트를 호스트의 8090번에 매핑합니다.

    powershell
    PS C:\Users\sakimura\Documents\Programs> docker run -itd -p 8090:8000 --name django_hello django_hello
    069eb3777790f092bcd8825ce2b3352f939876e17ddb06e85d85775c6baa3cfd
    PS C:\Users\sakimura\Documents\Programs> docker ps
    CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS                    NAMES
    e81d8fcebd80   django_hello   "/bin/bash"   49 seconds ago   Up 49 seconds   0.0.0.0:8090->8000/tcp   django_hello
    

    3. API 생성



    왼쪽 하단의 Open a remote window그런 다음 Remote-Containers: Attach to Running Container...

    방금 시작한 컨테이너가 나오므로 누르면, 새롭게 VSCode의 윈도우가 일어나,
    컨테이너 내에 액세스할 수 있습니다.


    VSCode에서 Ctrl + Shift + @ 에서 터미널을 열고 /opt 에서 Django 프로젝트를 만든 후 프로젝트로 이동하여 Django 앱을 만듭니다.

    bash
    [root@e81d8fcebd80 opt]# pwd
    /opt
    [root@e81d8fcebd80 opt]# django-admin startproject sampleproject
    [root@e81d8fcebd80 opt]# cd sampleproject
    [root@e81d8fcebd80 sampleproject]# django-admin startapp hello 
    

    프로젝트 디렉토리의 장고 설정 파일, URL 디스패처를 각각 편집합니다.

    /opt/sampleproject/sampleproject/settings.py
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework', # 追加
    ]
    

    /opt/sampleproject/sampleproject/urls.py
    """sampleproject URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/3.1/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.conf.urls import include, url # 追加
    from django.contrib import admin
    from django.urls import path
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'^hello', include('hello.urls', namespace='hello')), # 追加
    ]
    

    새 응용 프로그램 디렉터리 URL 디스패처를 만든 다음 views.py를 편집합니다.

    /opt/sampleproject/hello/urls.py
    from django.urls import path
    from . import views
    
    app_name = 'hello'
    urlpatterns = [
        path('', views.hello_world),
    ]
    

    /opt/sampleproject/hello/views.py
    from rest_framework.response import Response
    from rest_framework.decorators import api_view
    
    @api_view(['GET'])
    def hello_world(request):
        return Response({"message": "Hello, world!"})
    

    4. API 시작



    준비가 되었으므로 터미널에서 다음 명령을 실행하여 장고 내장 서버에서 시작합니다.

    bash
    [root@e81d8fcebd80 sampleproject]# python3 /opt/sampleproject/manage.py runserver 0.0.0.0:8000
    

    5. 동작 확인



    http://localhost:8090/hello 에 브라우저로 액세스합니다. 물론 curl 하지만 가능합니다.

    이 화면이 표시되면 OK입니다!
    이번에는 별로 좋지 않지만 관리 콘솔을 잘 다루면 상당히 API 개발이 진행됩니다.

    덧붙여서 원시 JSON을 확인하고 싶을 때는 http://localhost:8090/hello?format=json이라고하면 됩니다.


    요약



    수고하셨습니다.
    Django REST Framework를 활용하여 상당히 빨리 API를 구현할 수있었습니다.
    CRUD도 포함한 RESTful-API의 구현이나 프로덕션을 의식한 Web/WSGI 서버의 도입은 또 다른 기사에 쓰려고 합니다.

    참고 URL


  • Django REST Framework를 사용하여 폭속으로 API 구현
  • Django REST Framework 사용법 노트
  • [Django REST Framework] View 의 사용법을 정리해 보았다
  • 좋은 웹페이지 즐겨찾기