python / / 2024. 8. 16. 07:41

[fastapi] Path와 Query 매개변수를 Request Body와 함께 사용하는 방법

1. 기본 개념: Path, Query, 그리고 Request Body

  • Path 매개변수는 URL 경로에 포함된 변수이다. 예를 들어, /items/{item_id}에서 item_id는 Path 매개변수이다.
  • Query 매개변수는 URL의 ?key=value 형식으로 전달되는 변수이다. 예를 들어, /items/?skip=0&limit=10에서 skiplimit은 Query 매개변수다.
  • Request Body는 일반적으로 POST, PUT 등의 요청에서 JSON, XML, 또는 다른 형식으로 전송되는 데이터를 말한다.

이 세 가지를 혼합하여 사용하는 것은 API에서 매우 유용하며, 클라이언트가 경로와 쿼리 파라미터로 특정 리소스를 식별하거나 요청을 필터링하면서, 본문에서 더 많은 데이터를 전송할 수 있게 한다.

2. Path와 Query 매개변수를 Request Body와 함께 사용하기

FastAPI에서 Path, Query, 그리고 Request Body를 함께 사용하는 방법은 매우 직관적이다. FastAPI는 각 데이터 소스(Path, Query, Body)를 명확하게 구분하여 처리할 수 있도록 설계되어 있다.

예제 코드: Path, Query, Request Body의 조합
from fastapi import FastAPI, Path, Query, Body
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

@app.put("/items/{item_id}")
async def update_item(
    item_id: int = Path(..., title="The ID of the item to update"),
    q: str | None = Query(None, max_length=50),
    item: Item = Body(...)
):
    results = {"item_id": item_id, "item": item}
    if q:
        results.update({"q": q})
    return results

위 코드에서는 Path, Query, Request Body를 함께 사용하는 방법을 보여준다.

  • Path 매개변수 item_id: 이 매개변수는 URL 경로에서 받아온다. 이 매개변수를 사용해 특정 아이템을 지정할 수 있다.
  • Query 매개변수 q: 이 매개변수는 URL의 쿼리 스트링에서 받아온다. 선택 사항이며, 아이템을 업데이트할 때 특정한 검색어로 필터링할 수 있다.
  • Request Body item: 이 매개변수는 HTTP 요청의 본문에서 JSON 형식으로 받아온다. 업데이트할 아이템의 데이터(예: 이름, 설명, 가격 등)를 포함한다.
실행 흐름
  1. 클라이언트가 PUT 요청을 /items/42?q=update와 함께 전송하면, item_id는 42로, q는 "update"로 설정된다.
  2. Request Body에 JSON 데이터를 포함시켜 { "name": "New Item", "description": "A new item description", "price": 10.99, "tax": 1.5 }와 같은 데이터를 보낸다.
  3. FastAPI는 해당 데이터를 적절히 매핑하고, item_id, q, item의 값을 update_item 함수로 전달한다.
  4. 이 함수는 아이템의 업데이트 결과를 JSON 형식으로 반환한다.

요청

PUT /items/1?q=update
content-Type: application/json

{
  "name": "apple",
  "description": "fresh apple",
  "price": 10000,
  "tax": 1000
}

실행결과

{
  "item_id": 1,
  "item": {
    "name": "apple",
    "description": "fresh apple",
    "price": 10000.0,
    "tax": 1000.0
  },
  "q": "update"
}

만일 Body를 item : {} 형식으로 전달하고 싶다면 어떻게 해야 할까? 아래 예처럼

PUT /items/1?q=update
content-Type: application/json

{
  "item": {
    "name": "apple",
    "description": "fresh apple",
    "price": 10000,
    "tax": 1000
  }
}

이런 경우는 Body의 속성 중 embed를 활용할 수 있다. embed=True로 사용하면 이름(item)에 맞는 값으로 매핑이 된다.

@app.put("/items/{item_id}")
async def update_item(
        item_id: int = Path(..., title="The ID of the item to update"),
        q: str | None = Query(None, max_length=50),
        item: Item = Body(..., embed=True)
):
    results = {"item_id": item_id, "item": item}
    if q:
        results.update({"q": q})
    return results

위처럼 embed=True 설정하면 된다.

3. Path와 Query 매개변수의 기본값 및 유효성 검사

Path와 Query 매개변수는 기본값을 가질 수 있으며, 유효성 검사를 위해 여러 제한 조건을 적용할 수 있다.

@app.put("/items/{item_id}")
async def update_item(
    item_id: int = Path(..., title="The ID of the item to update", ge=0),
    q: str | None = Query(None, max_length=50, regex="^update"),
    item: Item = Body(...)
):
  • item_id는 0 이상의 정수여야 한다(ge=0).
  • q는 최대 50자 길이의 문자열이며, "update"로 시작해야 한다(regex="^update").

이러한 유효성 검사는 API가 기대하는 데이터를 클라이언트가 정확히 제공하도록 도와준다.

4. 복합적인 Request Body와 Path/Query 매개변수 사용하기

더 복잡한 API를 설계할 때, Request Body에 복합적인 데이터를 포함시키면서 Path 및 Query 매개변수를 활용할 수 있다.

from typing import List

@app.put("/items/{item_id}")
async def update_item(
    item_id: int = Path(..., title="The ID of the item to update"),
    q: str | None = Query(None, max_length=50),
    items: List[Item] = Body(...)
):
    results = {"item_id": item_id, "items": items}
    if q:
        results.update({"q": q})
    return results

위 코드에서는 items라는 리스트를 Request Body로 받아온다. 이 리스트는 여러 개의 Item 객체를 포함할 수 있으며, FastAPI는 이를 자동으로 파싱하여 처리한다.

참고

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유