출처: https://fastapi.tiangolo.com/tutorial/body/
아래의 내용은 공식 사이트의 내용을 제 경험과 생각을 추가하여 다시 정리한 것 입니다.
서버로 데이터를 보내는 방법
FastAPI의 Request Body를 이해하기 전에 데이터 전송의 기본적인 접근 방식을 알아보겠습니다. Get 방식과 Post 방식을 중점적으로 알아보겠습니다.
Get 방식
GET
요청은 데이터를 URL의 일부로 전송합니다. 주로 쿼리 문자열(query string)을 통해 데이터를 서버에 전달하며, 이는 URL 끝에 ? 다음에 key=value 쌍으로 추가되면 각 쌍은 &로 구분됩니다. 아래는 쿼리 문자열이 포함된 URL의 예시입니다.
http://127.0.0.1:8000/items/?skip=0&limit=10
GET은 주로 서버에서 데이터를 검색할 때 사용됩니다. 예를 들어, 특정 Item을 요청하거나 검색할 때 사용됩니다.
URL 길이에는 제한이 있으므로 GET 요청에 전송할 수 있는 데이터 양에도 제한이 있습니다. 또한, 데이터가 URL에 노출되기 때문에 민감한 정보를 전송하는 데 적합하지 않습니다.
GET 요청은 캐시될 수 있으며, 북마크나 공유가 가능합니다.
FastAPI의 쿼리(Query) 매개변수는 GET 요청에 사용됩니다.
Post 방식
POST
요청은 데이터를 HTTP의 Request Body(요청의 본문)을 통해 전송합니다. 데이터는 URL에 노출되지 않으므로 민감한 정보를 전송하는 데 적합합니다. 또한, URL 길이에 제한이 없으므로 데이터 양에도 제한이 없습니다. 아래는 POST 요청의 예시입니다.
<!DOCTYPE html>
<html>
<head>
<title>Item 생성 폼</title>
</head>
<body>
<h2>새 Item 생성</h2>
<form action="http://localhost:8000/items/" method="post">
<label for="name">이름:</label>
<input type="text" id="name" name="name"><br><br>
<label for="description">설명:</label>
<input type="text" id="description" name="description"><br><br>
<label for="price">가격:</label>
<input type="number" id="price" name="price" step="0.01"><br><br>
<label for="tax">세금:</label>
<input type="number" id="tax" name="tax" step="0.01"><br><br>
<input type="submit" value="제출">
</form>
</body>
</html>
POST는 서버에 데이터를 생성하거나 수정할 때 주로 사용됩니다. 예를 들어, 새로운 사용자 등록, 폼 데이터 전송, 파일 업로드 등에 사용됩니다.
POST 요청은 GET에 비해 보안적으로 더 안전합니다. 데이터가 HTTP 요청 본문에 포함되어 URL에 노출되지 않기 때문입니다.
POST 요청은 일반적으로 캐시되지 않으며, 북마크나 URL 공유로 재사용하기 어렵습니다.
Put / Delete 방식
PUT
요청은 데이터를 서버에 업데이트할 때 사용됩니다. 예를 들어, 사용자 정보를 업데이트하거나, 파일을 업데이트할 때 사용됩니다. Request body에 업데이트할 데이터를 포함합니다.
DELETE
요청은 데이터를 서버에서 삭제할 때 사용됩니다. 예를 들어, 사용자 정보를 삭제하거나, 파일을 삭제할 때 사용됩니다. URL에 삭제할 데이터를 포함합니다. FastAPI의 경로 매개변수는 DELETE 요청에 사용됩니다.
Pydantic's BaseModel
클라이언트에서 API 서버로 Request Body로 데이터를 전송 할 때 FastAPI는 아래와 같이 Pydantic 모델을 사용합니다. Pydantic 모델은 FastAPI에서 사용되는 모델로, 데이터의 유효성 검사를 수행합니다.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel # Pydantic's BaseModel
class Item(BaseModel): # BaseModel 상속
# 속성 선언
name: str # str 타입, 필수
description: Union[str, None] = None # str 또는 None 타입, 선택
price: float # float 타입, 필수
tax: Union[float, None] = None # float 또는 None 타입, 선택
app = FastAPI()
@app.post("/items/") # POST 메소드
async def create_item(item: Item): # 경로, 쿼리 매개변수와 같은 패턴
return item
FastAPI의 수행 과정
Pydantic's BaseModel를 사용하여 Request Body로 데이터를 전송하면 FastAPI는 아래와 같은 과정을 수행합니다.
- Request Body를 JSON으로 읽습니다.
- 필요한 경우 해당 유형을 변환합니다.
- 데이터의 유효성을 확인합니다.
- 데이터가 유효하지 않은 경우 정확하고 명확한 오류를 반환하여 잘못된 데이터의 위치와 내용을 정확하게 나타냅니다.
- 매개변수 항목에 수신된 데이터를 제공합니다.
item
. - 함수에서 항목 유형으로 선언한 대로 (
Item
) 모든 속성과 해당 유형에 대한 편집기 지원(완료 등)도 제공됩니다. - 모델에 대한 JSON 스키마 정의를 생성하고 프로젝트에 적합한 경우 원하는 다른 곳에서도 사용할 수 있습니다.
- 이러한 스키마는 생성된 OpenAPI 스키마의 일부이며 자동 문서 UI에서 사용됩니다.
편집기 지원의 예시는 아래와 같습니다.
Request Body Test
위의 소스를 테스트를 하려면 Request Body로 데이터를 전송해야 합니다. "Request Body로 데이터를 전송하기 위해서는 웹 브라우저의 URL로 데이터를 전송할 수 없습니다. 대신, 클라이언트는 POST, PUT, PATCH 같은 HTTP 메소드를 사용하여 HTTP 요청의 본문(body)에 데이터를 포함시켜야 합니다. 이 방식은 주로 HTML 폼, JavaScript의 fetch API, 또는 프로그래밍 언어의 HTTP 클라이언트 라이브러리(예: Python의 requests)를 통해 수행됩니다.
HTML의 폼과 JavaScript의 fetch API를 사용하여 Request Body로 데이터를 전송하는 소스를 아래와 같이 추가하겠습니다.
from typing import Union
from fastapi import FastAPI
from fastapi.responses import HTMLResponse # HTMLResponse 추가
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
### 여기까지 기존 코드 ###
### HTML의 폼과 JavaScript의 fetch API를 사용하여 요청 및 데이터 전송 ###
@app.get("/items/new", response_class=HTMLResponse)
async def create_item_form():
html_content = """
<html>
<head>
<title>Item 생성</title>
<script>
async function submitForm(event) {
event.preventDefault(); // 폼의 기본 제출 동작 방지
// 폼 데이터를 JSON 객체로 변환
let formData = new FormData(event.target);
let jsonData = Object.fromEntries(formData.entries());
// fetch API를 사용하여 데이터를 JSON 형식으로 전송
let response = await fetch('/items/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(jsonData)
});
let result = await response.json();
// 결과를 화면에 표시
document.getElementById("result").textContent = JSON.stringify(result, null, 2);
}
</script>
</head>
<body>
<h2>새 Item 생성</h2>
<form onsubmit="submitForm(event)">
<input type="text" name="name" placeholder="이름" required>
<input type="text" name="description" placeholder="설명">
<input type="number" step="0.01" name="price" placeholder="가격" required>
<input type="number" step="0.01" name="tax" placeholder="세금">
<input type="submit" value="생성">
</form>
<pre id="result"></pre> <!-- 결과를 표시할 요소 -->
</body>
</html>
"""
return HTMLResponse(content=html_content)
HTML Form을 return 하는 URL을 호출합니다.
http://127.0.0.1:8000/items/new
항목의 값을 입력합니다.
Submit 버튼을 클릭하고 개발자 도구의 Console을 확인합니다.
Post 방식 테스트
위의 테스트는 HTML과 JavaScript로 화면을 구축하고 테스트를 진행했습니다. 이 방법은 상대적으로 번거롭게 느껴질 수 있습니다. HTTP POST/PUT 방식을 테스트하기 위해서는 몇 가지 간단하고 효율적인 방법이 있습니다.
- Postman 사용:
Postman은 API를 테스트하기 위한 인기 있는 도구입니다. GUI 기반으로 쉽게 사용할 수 있으며, 다양한 HTTP 메소드와 헤더, 본문 옵션을 제공합니다. - cURL 명령어 사용:
cURL은 커맨드 라인 도구로, 모든 유형의 HTTP 요청을 간단한 명령어로 보낼 수 있습니다. 터미널이나 명령 프롬프트에서 바로 사용할 수 있어 편리합니다. - Swagger UI 사용:
FastAPI와 같은 몇몇 프레임워크는 Swagger UI를 제공합니다. 이는 브라우저 기반 인터페이스를 통해 API 엔드포인트를 쉽게 테스트할 수 있게 해줍니다. - Python의 requests 라이브러리 사용:
Python 스크립트를 통해 간단하게 HTTP 요청을 보낼 수 있습니다. 이 방법은 자동화 및 스크립트 기반 테스트에 적합합니다. - HTTPie 사용:
HTTPie는 사용자 친화적인 커맨드 라인 HTTP 클라이언트입니다. JSON 지원이 용이하며, 명령어 구문이 간결해서 사용하기 쉽습니다.
자동 문서(FastAPI 제공)
FastAPI는 자동으로 문서를 생성합니다. 이는 Swagger UI를 통해 확인할 수 있습니다. Swagger UI는 API의 엔드포인트를 쉽게 테스트할 수 있는 브라우저 기반 인터페이스를 제공합니다.
http://127.0.0.1:8000/docs
위의 URL을 호출하면 아래의 화면이 나타납니다.
POST /items/
를 클릭하면 아래의 화면이 나타납니다.
Try it out
를 클릭하고 Request Body
에 데이터를 입력한 후 Execute
를 클릭합니다.
Response Body
에 Response 데이터가 표시됩니다.
'웹 프레임워크 > FastAPI' 카테고리의 다른 글
FastAPI - 06 (경로 매개변수와 숫자 유효성 검사) (0) | 2023.12.18 |
---|---|
FastAPI - 05 (쿼리 매개변수와 문자열 유효성 검사) (0) | 2023.12.17 |
FastAPI - 03 (쿼리(Query) 매개변수) (0) | 2023.12.15 |
FastAPI - 02 (경로(Path) 매개변수) (0) | 2023.12.15 |
FastAPI - 01 (FastAPI란?) (0) | 2023.12.15 |