본문으로 바로가기

[Python][Flask] 02. Route 구조설계 - Restx

category Launguage/Python 2022. 8. 13. 19:32

Flask 의 Blueprint 외에 RESTful API 개발을 위한 Flask-Restx 라는 라이브러리 있습니다.

해당 라이브러리에서는 Swagger와 같은 API 문서화 및 테스트와 Validation 등의 다양한 기능을 제공하며,

해당 포스트에서는 Flask-Restx 를 이용해 앞서 설명했던 Controller 와 Route 를 연동하는 방법에 대해 기술합니다.

Ref. https://flask-restx.readthedocs.io/en/latest/

 

restx 는 메소드 단위의 라우팅을 제공하는 Blueprint 와 다르게 Class 단위의 라우트 맵핑을 사용하도록 설계 되었습니다.

restx 의 라우트와 연동하기 위해서는 flask_restx 패키지의 Resource 클래스를 상속받는 클래스를 정의해야 하며, 이렇게 정의된 클래스 내에 get, post, put, delete.. 등의 메소드를 정의함으로써 Request Method 와 맵핑이 이루어집니다.

아래와 같은 순서로 코드를 작성합니다.

  1. flask_restx 패키지의 Resource, Namespace 를 import 합니다.
  2. Namespace 선언
  3. Resource Class 정의
  4. Resource Class 를 Namespace 에 등록
# /controllers/users.py

from flask_restx import Resource, Namespace


# Namespace 선언
ns = Namespace(name='api/v1/users', description='User APIs')

# '/api/v1/users' Endpoint 로 접근하는 Resource Class 선언
class User(Resource):
    def get(self):
        return 'user list'

    def post(self):
        created = 2
        return 'create', 201, {
            'x-resource-id': created,
            'x-resource-uri': '/api/users/{}'.format(created)
        }

# '/api/v1/users/<id>' Endpoint 로 접근하는 Resource Class 선언
class UserByIdx(Resource):

    def get(self, idx):
        return f'specific user {idx}', 200

    def put(self, idx):
        return 'update', 200, {
            'x-resource-id': idx,
            'x-resource-uri': '/api/users/{}'.format(idx)
        }

    def delete(self, idx):
        return f'delete {idx}', 204
        
# 선언된 Resource Class 를 Namespace에 등록
ns.add_resource(User, '/')
ns.add_resource(UserByIdx, '/<idx>')



# /controllers/__init__.py
# controller 에서 ns_user 를 직접 import 할 수 있도록 선언


from .users import ns as ns_user

__all__ = ['ns_user']

 

위에 정의 한 Route 정보를 api 인스턴스에 등록합니다.

# /bootstrap/__init__.py

from flask import Flask


def regist_api_route(app: Flask):
    from flask_restx import Api
    from controllers import ns_user

    api = Api(
        title='Restx APIs',
        version='1.0',
        description='Flask Restx Apis Example'
    )
    api.add_namespace(ns_user)  # Add User Route
    api.init_app(app)


def create_app():
    app = Flask(__name__)
    regist_api_route(app)
    return app

위 과정까지 완료가 되었다면 메인 라우트 '/' 에서 다음과 같은 Swagger 화면을 통해 등록된 Endpoint 에 대한 사양과 요청을 테스트 할 수 있습니다. (Swagger 에 대해 보다 상세한 내용은 다음장의 포스트에 기술할 예정입니다.)

에러 핸들링

# ImportError: cannot import name ‘parse_rule’ from ‘werkzeug.routing’
# Werkzeug 의 버전을 아래와 같이 Downgrade 합니다.
$ pip install Werkzeug==2.1.2