FastAPI - Body: Multiple Parameters

Kjjeddยท2026๋…„ 1์›” 13์ผ

FastAPI

๋ชฉ๋ก ๋ณด๊ธฐ
8/16
post-thumbnail

๐Ÿ“ฆ Body - Multiple Parameters

FastAPI์—์„œ Body ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋‹จ์ˆœํžˆ โ€œ์š”์ฒญ์— JSON์„ ๋‹ด๋Š”๋‹คโ€ ์ˆ˜์ค€์„ ๋„˜์–ด์„œ API ์„ค๊ณ„์˜ ๊ตฌ์กฐ ์ž์ฒด๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์š”์†Œ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Request Body์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋‹ด๋Š” ๊ฒฝ์šฐ, FastAPI๊ฐ€ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด์„ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š”์ง€๋ฅผ ๋‹จ๊ณ„์ ์œผ๋กœ ์ •๋ฆฌํ•œ๋‹ค.


๐Ÿ“š ์–ด์›์œผ๋กœ ์‹œ์ž‘ํ•˜๊ธฐ

Body๋Š” ์˜์–ด๋กœ ๋ชธํ†ต์„ ์˜๋ฏธํ•œ๋‹ค. HTTP ์š”์ฒญ๋„ ์‚ฌ๋žŒ์ฒ˜๋Ÿผ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ ์—ญํ•  ์‚ฌ๋žŒ์œผ๋กœ ๋น„์œ ํ•˜๋ฉด
Header ์š”์ฒญ์˜ ๋ฉ”ํƒ€ ์ •๋ณด ๋จธ๋ฆฌ (์ƒ๊ฐ, ํŒ๋‹จ)
Body ์‹ค์ œ ์ „๋‹ฌ ๋ฐ์ดํ„ฐ ๋ชธํ†ต (ํ•ต์‹ฌ ๋‚ด์šฉ๋ฌผ)

Parameter๋Š” ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ์ž…๋ ฅ๊ฐ’์ด๋‹ค.

๐Ÿ“ฆ FastAPI์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š”
์–ด๋””์—์„œ ์™”๋Š”์ง€์— ๋”ฐ๋ผ ์˜๋ฏธ๊ฐ€ ์™„์ „ํžˆ ๋‹ฌ๋ผ์ง„๋‹ค

๐Ÿšš FastAPI ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ ๊ฒฝ๋กœ

ํŒŒ๋ผ๋ฏธํ„ฐ ์œ ํ˜• ์ „๋‹ฌ ์œ„์น˜ ํƒ๋ฐฐ ๋น„์œ 
Path /items/{item_id} ๋ฐฐ์†ก์ง€ ์ฃผ์†Œ
Query ?q=๊ฒ€์ƒ‰์–ด ๋ฐฐ์†ก ์š”์ฒญ์‚ฌํ•ญ
Body HTTP ์š”์ฒญ ๋ณธ๋ฌธ ์ƒ์ž ์•ˆ ๋‚ด์šฉ๋ฌผ

์ด๋ฒˆ ๊ธ€์˜ ํ•ต์‹ฌ์€ โ€œBody ์•ˆ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ƒ์ž๋ฅผ ๋„ฃ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?โ€์ด๋‹ค.


๐Ÿ›  ์‹ค์Šต ํ™˜๊ฒฝ ์ค€๋น„

# ํ”„๋กœ์ ํŠธ ํด๋” ์ƒ์„ฑ
mkdir fastapi-body-params
cd fastapi-body-params

# ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# FastAPI ์„ค์น˜
pip install "fastapi[standard]"

โœ๏ธ ์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ: Body ํŒŒ๋ผ๋ฏธํ„ฐ 1๊ฐœ

from fastapi import FastAPI
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, item: Item):
    return {
        "item_id": item_id,
        "item": item
    }

โ€ข ํด๋ผ์ด์–ธํŠธ๋Š” JSON ๊ฐ์ฒด๋ฅผ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค
โ€ข ํ•„์ˆ˜ ํ•„๋“œ: name, price
โ€ข ์„ ํƒ ํ•„๋“œ: description, tax
โ€ข ํƒ€์ž…์ด ๋‹ค๋ฅด๋ฉด ์š”์ฒญ ๋‹จ๊ณ„์—์„œ ์ž๋™์œผ๋กœ ๊ฑฐ๋ถ€๋จ

ํ…Œ์ŠคํŠธ: Swagger UI์—์„œ ํ•ด๋‹น Request Body ์ž…๋ ฅ ํ›„ "Try it out" ํด๋ฆญ

{
  "name": "๋…ธํŠธ๋ถ",
  "description": "๊ฐœ๋ฐœ์šฉ ๋งฅ๋ถ",
  "price": 2500000,
  "tax": 250000
}

๊ฒฐ๊ณผ:

โœ” 1. Path ํŒŒ๋ผ๋ฏธํ„ฐ ์ •์ƒ ์ˆ˜์‹ 
โ†’ URL์˜ {item_id}๊ฐ€ ์ •ํ™•ํžˆ ๋งคํ•‘๋จ

โœ” 2. Request Body๊ฐ€ ๋ชจ๋ธ๋กœ ํŒŒ์‹ฑ๋จ
โ†’ JSON โ†’ Item ๊ฐ์ฒด โ†’ ๋‹ค์‹œ JSON

โœ… Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 1๊ฐœ์ผ ๋•Œ๋Š”
๋ชจ๋ธ์˜ ํ•„๋“œ๊ฐ€ JSON ์ตœ์ƒ์œ„์— ์œ„์น˜ํ•œ๋‹ค

โœ๏ธ ๋‘ ๋ฒˆ์งธ ์ฝ”๋“œ: Body ํŒŒ๋ผ๋ฏธํ„ฐ 2๊ฐœ๋กœ ํ™•์žฅ

์ด์ œ Body ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•ด๋ณด์ž.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class User(BaseModel):
    username: str
    full_name: str | None = None

@app.put("/items/{item_id}")
async def update_item(
    item_id: int,
    item: Item,
    user: User
):
    return {
        "item_id": item_id,
        "item": item,
        "user": user
    }

Swagger UI์—์„œ ํ™•์ธํ•˜๋ฉด Request Body์˜ ํ˜•ํƒœ๊ฐ€ ๋‹ฌ๋ผ์ง„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ณ€๊ฒฝ๋œ Request Body๊ตฌ์กฐ:

{
  "item": {
    "name": "๋…ธํŠธ๋ถ",
    "description": "๊ฐœ๋ฐœ์šฉ ๋งฅ๋ถ",
    "price": 2500000,
    "tax": 250000
  },
  "user": {
    "username": "Jay",
    "full_name": "๊น€์ข…์–ธ"
  }
}

๊ฒฐ๊ณผ:

ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 2๊ฐœ๊ฐ€ ๋˜๋‹ˆ๊นŒ ๊ฐ ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์ด key๊ฐ€ ๋˜๊ณ , ๊ทธ ์•ˆ์— ๋ชจ๋ธ์˜ ํ•„๋“œ๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค. ๐Ÿ‘‰ FastAPI๊ฐ€ ์ž๋™์œผ๋กœ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ•ด์คŒ!
โœ… Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 2๊ฐœ ์ด์ƒ๊ฐ€ ๋˜๋ฉด
FastAPI๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์„ ํ‚ค๋กœ ์‚ฌ์šฉํ•ด
JSON์„ ์ž๋™์œผ๋กœ ๊ฐ์‹ผ๋‹ค

๐Ÿง  ํ•ต์‹ฌ ๊ทœ์น™ ์ •๋ฆฌ

Body ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐœ์ˆ˜ JSON ๊ตฌ์กฐ
1๊ฐœ ๋ชจ๋ธ ํ•„๋“œ๊ฐ€ ์ตœ์ƒ์œ„
2๊ฐœ ์ด์ƒ ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์ด ํ‚ค๊ฐ€ ๋จ

์ด ๋™์ž‘์€ ์˜ต์…˜์ด ์•„๋‹ˆ๋ผ FastAPI์˜ ๊ธฐ๋ณธ ๊ทœ์น™์ด๋‹ค.

๐Ÿ‘‰ Body ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚˜๋Š” ์ˆœ๊ฐ„ API์˜ JSON ์Šคํ‚ค๋งˆ๋„ ํ•จ๊ป˜ ๋ฐ”๋€๋‹ค


๐Ÿง  ์ด๋ก ๊ณผ ํ•ต์‹ฌ ๋‚ด์šฉ

์ด์ œ โ€œ์™œ FastAPI๊ฐ€ ์ด๋ ‡๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€โ€๋ฅผ ๊ตฌ์กฐ์ ์œผ๋กœ ์ •๋ฆฌํ•ด๋ณด์ž. ํ•ต์‹ฌ์€ FastAPI์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์ž๋™ ์ธ์‹ ๊ทœ์น™์ด๋‹ค.

๐Ÿ” FastAPI ํŒŒ๋ผ๋ฏธํ„ฐ ์ž๋™ ์ธ์‹ ๊ทœ์น™

FastAPI๋Š” ํ•จ์ˆ˜์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋งŒ ๋ณด๊ณ  ๊ฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์–ด๋””์—์„œ ๊ฐ€์ ธ์˜ฌ์ง€ ์ž๋™์œผ๋กœ ๊ฒฐ์ •ํ•œ๋‹ค.

ํŒ๋‹จ ๊ธฐ์ค€ ํŒŒ๋ผ๋ฏธํ„ฐ ์œ ํ˜•
URL ๊ฒฝ๋กœ์— {์ด๋ฆ„}์ด ์กด์žฌ Path Parameter
Pydantic ๋ชจ๋ธ ํƒ€์ž… Body Parameter
๋‹จ์ˆœ ํƒ€์ž… (int, str, float ๋“ฑ) Query Parameter
๐Ÿ’ก FastAPI๋Š” ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ์œ„์น˜๋งŒ ๋ณด๊ณ  ํŒ๋‹จํ•œ๋‹ค
๋ณ„๋„์˜ ์„ค์ •์ด ์—†์–ด๋„ ์ž๋™์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค

๐Ÿงฉ ํŒŒ๋ผ๋ฏธํ„ฐ ํ˜ผํ•ฉ ์˜ˆ์ œ

ํ•˜๋‚˜์˜ API์—์„œ Path ยท Query ยท Body๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ๋ฅผ ๋ณด์ž.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.put("/items/{item_id}")
async def update_item(
    item_id: int,        # Path
    item: Item,          # Body
    q: str | None = None # Query
):
    result = {
        "item_id": item_id,
        "item": item
    }
    if q:
        result["q"] = q
    return result

FastAPI๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด์„ํ•œ๋‹ค.

  • item_id โ†’ URL์— ์žˆ์œผ๋ฏ€๋กœ Path
  • item โ†’ Pydantic ๋ชจ๋ธ์ด๋ฏ€๋กœ Body
  • q โ†’ ๋‹จ์ˆœ ํƒ€์ž… + ๊ธฐ๋ณธ๊ฐ’ โ†’ Query

๐Ÿ“ฆ Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๋•Œ์˜ ๋‚ด๋ถ€ ๋™์ž‘

์™œ Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 2๊ฐœ ์ด์ƒ์ด๋ฉด JSON ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€”๊นŒ?

์ด์œ ๋Š” ๋‹จ์ˆœํ•˜๋‹ค.

โš ๏ธ JSON์—๋Š” โ€œ์ด ๊ฐ’์ด ์–ด๋–ค ํŒŒ๋ผ๋ฏธํ„ฐ์ธ์ง€โ€๋ฅผ
๊ตฌ๋ถ„ํ•  ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ!

Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 1๊ฐœ์ผ ๋•Œ๋Š” ๋ชจํ˜ธํ•˜์ง€ ์•Š๋‹ค.

{
  "name": "๋…ธํŠธ๋ถ",
  "price": 2500000
}

ํ•˜์ง€๋งŒ Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 2๊ฐœ๋ผ๋ฉด?

{
  "name": "๋…ธํŠธ๋ถ",
  "price": 2500000,
  "username": "jay"
}

์ด ๊ตฌ์กฐ์—์„œ๋Š” ์–ด๋””๊นŒ์ง€๊ฐ€ Item์ด๊ณ , ์–ด๋””๋ถ€ํ„ฐ User์ธ์ง€ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†๋‹ค.

๊ทธ๋ž˜์„œ FastAPI๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์„ JSON์˜ ํ‚ค๋กœ ์‚ฌ์šฉํ•œ๋‹ค.


๐Ÿงฑ Body()๋กœ ๋‹จ์ˆœ ํƒ€์ž…์„ Body์— ํฌํ•จํ•˜๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ int, str ๊ฐ™์€ ๋‹จ์ˆœ ํƒ€์ž…์€ Query ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ธ์‹๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๋‹จ์ˆœ ๊ฐ’๋„ Body์— ๋„ฃ๊ณ  ์‹ถ๋‹ค๋ฉด Body()๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

from fastapi import FastAPI, Body
from pydantic import BaseModel
from typing import Annotated

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.put("/items/{item_id}")
async def update_item(
    item_id: int,
    item: Item,
    importance: Annotated[int, Body()]
):
    return {
        "item_id": item_id,
        "item": item,
        "importance": importance
    }

์š”์ฒญ Body๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

{
  "item": {
    "name": "๋…ธํŠธ๋ถ",
    "price": 2500000
  },
  "importance": 5
}

๐Ÿงฉ embed ์˜ต์…˜: Body ํ•˜๋‚˜๋„ ๊ฐ์‹ธ๊ณ  ์‹ถ์„ ๋•Œ

Body ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ 1๊ฐœ์ผ ๋•Œ๋„ JSON์„ ํ‚ค๋กœ ๊ฐ์‹ธ๊ณ  ์‹ถ๋‹ค๋ฉด embed=True๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

from fastapi import FastAPI, Body
from pydantic import BaseModel
from typing import Annotated

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.put("/items/{item_id}")
async def update_item(
    item_id: int,
    item: Annotated[Item, Body(embed=True)]
):
    return {
        "item_id": item_id,
        "item": item
    }

์š”์ฒญ JSON ๋น„๊ต:

์˜ต์…˜ JSON ๊ตฌ์กฐ
embed=False (๊ธฐ๋ณธ)
{ "name": "๋…ธํŠธ๋ถ", "price": 2500000 }
embed=True
{ "item": { "name": "๋…ธํŠธ๋ถ", "price": 2500000 } }
๐Ÿ’ก ์—ฌ๋Ÿฌ API์˜ JSON ๊ตฌ์กฐ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
embed=True๋Š” ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค

๐Ÿ“Œ ๊ธฐ์–ตํ•ด์•ผ ํ•  ํฌ์ธํŠธ

  • Body ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐœ์ˆ˜๋Š” JSON ์Šคํ‚ค๋งˆ๋ฅผ ๋ฐ”๊พผ๋‹ค
  • ์ด ๋ณ€๊ฒฝ์€ FastAPI์˜ ์ž๋™ ๊ทœ์น™์ด๋‹ค
  • ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐ˜๋“œ์‹œ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์ „์— ํ•ฉ์˜ํ•ด์•ผ ํ•œ๋‹ค
  • embed, Body() ์˜ต์…˜์€ ์„ค๊ณ„ ๋‹จ๊ณ„์—์„œ ๊ฒฐ์ •ํ•œ๋‹ค
โœ… Body ์„ค๊ณ„๋Š” ๋‹จ์ˆœ ๊ตฌํ˜„ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ
API ๊ณ„์•ฝ(Contract)์˜ ๋ฌธ์ œ๋‹ค

๐Ÿงพ ์ตœ์ข… ์ •๋ฆฌ

๊ฐœ๋… ํ•ต์‹ฌ ์š”์•ฝ
Body 1๊ฐœ ๋ชจ๋ธ ํ•„๋“œ๊ฐ€ ์ตœ์ƒ์œ„
Body 2๊ฐœ ์ด์ƒ ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„์œผ๋กœ ์ž๋™ ๊ฐ์Œˆ
๋‹จ์ˆœ ํƒ€์ž… ๊ธฐ๋ณธ์€ Query
Body() ๋‹จ์ˆœ ํƒ€์ž…์„ Body๋กœ ์ฒ˜๋ฆฌ
embed=True ๋‹จ์ผ Body๋„ ํ‚ค๋กœ ๊ฐ์Œˆ
๐ŸŽฏ ์š”์•ฝ
FastAPI์˜ Body ์„ค๊ณ„๋Š” JSON ๊ตฌ์กฐ ์„ค๊ณ„ ๊ทธ ์ž์ฒด๋‹ค
profile
Gongbuhaja

0๊ฐœ์˜ ๋Œ“๊ธ€