๐Ÿงฑ FastAPI ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งŒ๋“ค๊ธฐ

๐Ÿ•’ ์•ฝ 2๋ถ„ ์ฝ๋Š” ๋ฐ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค

์ด์ „๊ธ€ ๋ณด๊ธฐ(FastAPI ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •)

โ€“ Hello, FastAPI! ๊ทธ๋‹ค์Œ ๋‹จ๊ณ„, FastAPI ์•ฑ ๋งŒ๋“ค๊ธฐ

“๊ธฐ์ดˆ๋ถ€ํ„ฐ ํƒ„ํƒ„ํ•˜๊ฒŒ!”
์ด์ œ ํ™˜๊ฒฝ ์„ค์ •๋„ ๋๋‚ฌ์œผ๋‹ˆ, FastAPI์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๋“ค์„ ์ง์ ‘ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•ด๋ณด๋ฉฐ ํ•˜๋‚˜ํ•˜๋‚˜ ์ตํ˜€๋ณผ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋ผ์šฐํŒ…, ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜, ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜, POST ์š”์ฒญ ์ฒ˜๋ฆฌ๊นŒ์ง€ FastAPI์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ๊ฒฝํ—˜ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


โœ… ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ๋งŒ๋“ค๊ธฐ

์šฐ์„  ๊น”๋”ํ•œ ๊ตฌ์กฐ๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ ํด๋” ๊ตฌ์„ฑ์„ ์žก์•„์ค„๊ฒŒ์š”.

fastapi-tutorial/
โ”‚
โ”œโ”€โ”€ main.py
โ”œโ”€โ”€ models.py
โ”œโ”€โ”€ schemas.py
โ””โ”€โ”€ requirements.txt

์ด ๊ตฌ์กฐ๋Š” ์•ž์œผ๋กœ ๊ทœ๋ชจ๊ฐ€ ์ปค์ ธ๋„ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์šด ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.
์ง€๊ธˆ์€ ๊ฐ„๋‹จํ•˜๊ฒŒ, ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ main.py์— ์ž‘์„ฑํ•˜๋ฉด์„œ ๊ธฐ๋Šฅ๋ณ„๋กœ ๊ตฌ๋ถ„๋งŒ ์ดํ•ดํ•ด๋ณผ๊ฒŒ์š”.


๐Ÿšฆ 1. ๋ผ์šฐํŒ…(Routing) ์ดํ•ดํ•˜๊ธฐ

FastAPI๋Š” URL ๊ฒฝ๋กœ์™€ Python ํ•จ์ˆ˜(์—”๋“œํฌ์ธํŠธ)๋ฅผ ์—ฐ๊ฒฐํ•ด์„œ API๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ผ์šฐํŒ…์ด๋ผ๊ณ  ํ•ด์š”.

main.py ํŒŒ์ผ์„ ์—ด๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์„ธ์š”:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root():
    return {"message": "Welcome to FastAPI!"}

@app.get("/hello")
def say_hello():
    return {"message": "Hello, World!"}

์‹คํ–‰ ๋ฐฉ๋ฒ•

ํ„ฐ๋ฏธ๋„์—์„œ ์•„๋ž˜ ๋ช…๋ น์–ด ์ž…๋ ฅ:

uvicorn main:app --reload

๋ธŒ๋ผ์šฐ์ €๋กœ ์ ‘์†:

  • http://127.0.0.1:8000/ โ†’ Welcome ๋ฉ”์‹œ์ง€
  • http://127.0.0.1:8000/hello โ†’ Hello ๋ฉ”์‹œ์ง€

๐Ÿ“ฆ 2. ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ (Path Parameters)

ํŠน์ •ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ URL ๊ฒฝ๋กœ๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ: /users/3 โ†’ ์‚ฌ์šฉ์ž ID๊ฐ€ 3์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ณ  ์‹ถ์„ ๋•Œ

@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"user_id": user_id}
  • user_id๋Š” ํ•จ์ˆ˜ ์ธ์ž์ด์ž, URL์˜ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.
  • int ํƒ€์ž… ํžŒํŠธ ๋•๋ถ„์— ์ˆซ์ž๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ ์ž๋™ ์˜ค๋ฅ˜ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์ ‘์† ์˜ˆ:

http://127.0.0.1:8000/users/42
โ†’ {"user_id": 42}

๐Ÿ” 3. ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ (Query Parameters)

์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ?key=value ํ˜•์‹์œผ๋กœ ์ „๋‹ฌ๋˜๋Š” ์ถ”๊ฐ€ ์ •๋ณด์ž…๋‹ˆ๋‹ค.

@app.get("/items/")
def read_item(q: str = "default"):
    return {"query": q}

์ ‘์† ์˜ˆ:

  • /items/?q=fastapi โ†’ {"query": "fastapi"}
  • /items/ โ†’ {"query": "default"}

q: str = "default"๋Š” ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

๋ณต์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ๊ฐ€๋Šฅ:

@app.get("/search/")
def search(keyword: str, page: int = 1):
    return {"keyword": keyword, "page": page}

์˜ˆ:

/search/?keyword=python&page=2
โ†’ {"keyword": "python", "page": 2}

๐Ÿ“ฌ 4. POST ์š”์ฒญ๊ณผ Request Body ์ฒ˜๋ฆฌ

๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„์— ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” POST ์š”์ฒญ๋„ FastAPI์—์„  ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

1. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ์ •์˜ (Pydantic ์‚ฌ์šฉ)

from pydantic import BaseModel

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

2. POST ์š”์ฒญ ํ•ธ๋“ค๋Ÿฌ ์ž‘์„ฑ

@app.post("/items/")
def create_item(item: Item):
    return {"received_item": item}

์ด์ œ Swagger ๋ฌธ์„œ(โ†’ /docs)์—์„œ ์ง์ ‘ POST ์š”์ฒญ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์š”์ฒญ ๋ณธ๋ฌธ(JSON):

{
  "name": "Laptop",
  "price": 1299.99,
  "description": "High-performance laptop"
}

์‘๋‹ต:

{
  "received_item": {
    "name": "Laptop",
    "price": 1299.99,
    "description": "High-performance laptop"
  }
}

๐Ÿงช 5. ํ•„์ˆ˜ ํ…Œ์ŠคํŠธ ํฌ์ธํŠธ ์š”์•ฝ

๊ธฐ๋Šฅ๊ฒฝ๋กœ์„ค๋ช…
๊ธฐ๋ณธ ๋ผ์šฐํŒ…/Welcome ๋ฉ”์‹œ์ง€ ๋ฐ˜ํ™˜
๋‹จ์ˆœ GET/helloHello ๋ฉ”์‹œ์ง€
๊ฒฝ๋กœ ๋ณ€์ˆ˜/users/1์‚ฌ์šฉ์ž ID ๋ฐ˜ํ™˜
์ฟผ๋ฆฌ ๋ณ€์ˆ˜/items/?q=fastapi๋ฌธ์ž์—ด ์ž…๋ ฅ ๋ฐ›์•„ ๋ฐ˜ํ™˜
POST ์š”์ฒญ/items/JSON ๋ณธ๋ฌธ ๋ฐ›์•„ ์ฒ˜๋ฆฌ

๐Ÿ›  ํŒ: FastAPI ๋””๋ฒ„๊น…๊ณผ ๋ฆฌ๋กœ๋“œ

  • --reload ์˜ต์…˜์„ ํ•ญ์ƒ ์‚ฌ์šฉํ•˜์„ธ์š”. ํŒŒ์ผ ์ €์žฅ ์‹œ ์„œ๋ฒ„๊ฐ€ ์ž๋™์œผ๋กœ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.
  • ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ์ง๊ด€์ ์œผ๋กœ ์ถœ๋ ฅ๋˜๋ฏ€๋กœ ๋””๋ฒ„๊น…์ด ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.
  • Swagger UI์—์„œ ์ง์ ‘ API ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. GUI ๊ธฐ๋ฐ˜์ด๋ผ ์ดˆ๋ณด์ž์—๊ฒŒ ๋งค์šฐ ์นœ์ ˆํ•ฉ๋‹ˆ๋‹ค.

๐Ÿงพ ๋งˆ๋ฌด๋ฆฌ: FastAPI๋Š” ์ง„์ž… ์žฅ๋ฒฝ์ด ๋‚ฎ์ง€๋งŒ ๊ฐ•๋ ฅํ•˜๋‹ค

์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ FastAPI์—์„œ ๊ฐ€์žฅ ํ•ต์‹ฌ์ด ๋˜๋Š” ๊ธฐ๋Šฅ๋“ค์ธ ๋ผ์šฐํŒ…, ๊ฒฝ๋กœ/์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜, POST ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. Flask๋ณด๋‹ค ํ›จ์”ฌ ์ •๋ˆ๋œ ๊ตฌ์กฐ๋กœ, ๋” ๋น ๋ฅด๊ณ  ๋ช…ํ™•ํ•œ API๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ์‹ค๊ฐ๋‚˜์ฃ ?

๋‹ค์Œ ํŽธ์—์„œ๋Š” ์‘๋‹ต ๋ชจ๋ธ, ์ƒํƒœ ์ฝ”๋“œ ์ฒ˜๋ฆฌ, ์˜ˆ์™ธ ํ•ธ๋“ค๋ง ๋“ฑ์— ๋Œ€ํ•ด ๋ฐฐ์›Œ๋ณด๋ฉฐ ํ•œ์ธต ๋” ํƒ„ํƒ„ํ•œ API๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค!

FastAPI ๊ณต์‹ ๋ฌธ์„œ : https://fastapi.tiangolo.com/ko/

fastapi-logo,fastapi-๊ฐœ๋ฐœ-ํ™˜๊ฒฝ-์„ค์ •, fastapi-์•ฑ-๋งŒ๋“ค๊ธฐ