📌 책 관리 REST API 만들기 - Flask 실습
문제: 책 관리 API 만들기
개요
책 정보를 관리하는 간단한 RESTful API를 만들어야 합니다. 이 API는 책의 목록을 보여주고, 새로운 책을 추가하며, 특정 책의 정보를 업데이트하고 삭제할 수 있어야 합니다.
요구 사항
- 애플리케이션 설정 (app.py)
- Flask 애플리케이션을 생성하고, Flask-Smorest API를 설정합니다.
- 책 스키마 정의 (schemas.py)
- Marshmallow를 사용하여 책 정보를 위한 스키마를 정의합니다. 책은 최소한 'title'(제목)과 'author'(저자) 필드를 가져야 합니다.
- API 엔드포인트 구현 (api.py)
- 책 목록을 보여주는 GET 엔드포인트를 만듭니다.
- 새 책을 추가하는 POST 엔드포인트를 만듭니다.
- 특정 책의 정보를 업데이트하는 PUT 엔드포인트를 만듭니다.
- 특정 책을 삭제하는 DELETE 엔드포인트를 만듭니다.
- 데이터 저장소
- 책의 데이터는 메모리 내의 간단한 리스트로 관리합니다.
예시 코드
1. app.py - 애플리케이션 설정
from flask import Flask
from flask_smorest import Api
app = Flask(__name__)
# OpenAPI 설정
app.config['API_TITLE'] = 'Book API'
app.config['API_VERSION'] = 'v1'
app.config['OPENAPI_VERSION'] = '3.0.2'
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
api = Api(app)
api.register_blueprint(book_blp)
if __name__ == '__main__':
app.run(debug=True)
설명
- Flask 애플리케이션을 초기화하고, Swagger UI 경로와 설정을 추가합니다. Swagger UI는 API 문서화 및 테스트를 위한 도구로 사용됩니다.
- Flask-Smorest API를 설정하고, book_blp라는 블루프린트를 등록하여 API 엔드포인트를 관리합니다.
2. schemas.py - 책 스키마 정의
from marshmallow import Schema, fields
class BookSchema(Schema):
id = fields.Int(dump_only=True) # ID 필드는 서버에서 관리
title = fields.String(required=True) # 책 제목은 필수
author = fields.String(required=True) # 책 저자도 필수
설명
- Marshmallow를 사용하여 책 스키마를 정의합니다. 이 스키마는 책 데이터의 검증, 직렬화 및 역직렬화를 처리합니다.
- id 필드는 자동으로 생성되어 반환되며, title과 author는 필수 필드로 설정됩니다.
3. api.py - API 엔드포인트 구현
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from schemas import BookSchema
book_blp = Blueprint('books', 'books', url_prefix='/books', description='Operations on books')
books = []
@book_blp.route('/')
class BookList(MethodView):
@book_blp.response(200, BookSchema(many=True))
def get(self):
return books
@book_blp.arguments(BookSchema)
@book_blp.response(201, BookSchema)
def post(self, new_data):
new_data['id'] = len(books) + 1
books.append(new_data)
return new_data
@book_blp.route('/<int:book_id>')
class Book(MethodView):
@book_blp.response(200, BookSchema)
def get(self, book_id):
book = next((book for book in books if book['id'] == book_id), None)
if book is None:
abort(404, message="Book not found.")
return book
@book_blp.arguments(BookSchema)
@book_blp.response(200, BookSchema)
def put(self, new_data, book_id):
book = next((book for book in books if book['id'] == book_id), None)
if book is None:
abort(404, message="Book not found.")
book.update(new_data)
return book
@book_blp.response(204)
def delete(self, book_id):
global books
book = next((book for book in books if book['id'] == book_id), None)
if book is None:
abort(404, message="Book not found.")
books = [book for book in books if book['id'] != book_id]
return ''
설명
- BookList 클래스: 모든 책 목록을 반환하는 GET 메소드와 새 책을 추가하는 POST 메소드를 처리합니다.
- GET 메소드는 books 리스트에서 모든 책을 반환합니다.
- POST 메소드는 새 책을 추가하고, 책에 id를 자동으로 할당합니다.
- Book 클래스: 특정 책을 조회, 수정, 삭제하는 GET, PUT, DELETE 메소드를 처리합니다.
- GET 메소드는 특정 book_id에 해당하는 책을 찾고 반환합니다.
- PUT 메소드는 특정 책의 정보를 업데이트합니다.
- DELETE 메소드는 특정 책을 삭제합니다.
파일별 설명
1. app.py
- Flask 애플리케이션과 Flask-Smorest API의 기본 설정을 포함합니다. Swagger UI 경로도 설정됩니다.
2. schemas.py
- 책 정보를 위한 스키마를 정의합니다. 책의 제목과 저자는 필수 항목이며, 책의 고유 ID는 서버에서 관리됩니다.
3. api.py
- 책 목록을 관리하는 API 엔드포인트를 구현합니다. 각 HTTP 메소드(GET, POST, PUT, DELETE)를 사용하여 책 목록을 조회, 추가, 수정, 삭제할 수 있습니다.
API 엔드포인트 요약
HTTP MethodDescriptionURL PathResponse Data
GET |
모든 책 목록을 반환 |
/books/ |
책 목록 (JSON) |
POST |
새 책 추가 |
/books/ |
추가된 책 (JSON) |
GET |
특정 ID의 책 반환 |
/books/<book_id> |
특정 책 (JSON) |
PUT |
특정 ID의 책 정보 업데이트 |
/books/<book_id> |
업데이트된 책 (JSON) |
DELETE |
특정 ID의 책 삭제 |
/books/<book_id> |
없음 (HTTP 상태 204) |
추가 설명
Flask-Smorest와 Swagger UI
- Flask-Smorest를 사용하면 OpenAPI(Swagger) 스펙을 기반으로 한 문서를 자동으로 생성할 수 있습니다. Swagger UI는 이러한 문서를 시각적으로 확인하고, 직접 API를 테스트할 수 있는 기능을 제공합니다.
- Swagger UI는 **http://localhost:5000/swagger-ui**에서 확인할 수 있습니다.
Marshmallow 스키마 활용
- Marshmallow 스키마는 API 요청 및 응답 데이터를 검증하고 직렬화하는 데 사용됩니다. required=True와 같은 필수 필드 지정, dump_only=True와 같은 읽기 전용 필드를 설정할 수 있습니다.