FastAPI入門 — PythonでREST APIを最速で作る方法【コード例付き】

PythonのFastAPIを使ってREST APIを構築する方法を基礎から解説。環境構築、GET/POST/PUT/DELETEの実装、パスパラメーター、クエリパラメーター、リクエストボディ、非同期処理、自動ドキュメント生成まで、実際に動くコード例で学べます。

生成AI

FastAPI入門 — PythonでREST APIを最速で作る方法

この記事でわかること

  • WebAPIの基本的な仕組み — リクエストとレスポンスのやり取りを具体例で理解
  • FastAPIの環境構築と最初のAPI作成pip installから動作確認までの手順
  • GET/POST/PUT/DELETEの実装方法 — CRUDの各操作をコード例付きで解説
  • パスパラメーター・クエリパラメーター・リクエストボディの使い分け — いつどれを使うべきか
  • 非同期処理と自動ドキュメント生成 — FastAPIならではの便利機能

そもそもWebAPIとは?

WebAPIは、プログラム同士がネットワーク越しにデータをやり取りする仕組みです。

身近な例で説明すると、スマホの乗換案内アプリの裏側はこうなっています。

  1. リクエスト: スマホ(クライアント)が「A駅からB駅までのルートを教えて」とサーバーに送信
  2. レスポンス: サーバーが乗換情報をJSON形式で返す
  3. 表示: アプリが受け取ったデータを画面に表示

この「リクエストを送って、レスポンスを受け取る」のがWebAPIの基本です。

HTTPメソッドとCRUD操作の対応

WebAPIでは、やりたい操作に応じて4種類のHTTPメソッドを使い分けます。

HTTPメソッド 操作 具体例
GET データの取得 ユーザー情報の表示
POST データの登録 新規ユーザーの作成
PUT データの更新 プロフィールの変更
DELETE データの削除 アカウントの削除

なぜWebAPIを使うのか

WebAPIでクライアントとサーバーを分離するメリットは2つあります。

1. 変更に強い設計になる サーバー側のデータベースを変更しても、APIの仕様さえ変えなければクライアント側のコードは一切変更不要です。

2. 複数のクライアントから使える 同じAPIをスマホアプリ、Webアプリ、他のサーバーから呼び出せます。機能を一度作れば使い回しが利きます。


FastAPIの環境構築

インストール

pip install fastapi
pip install "uvicorn[standard]"

fastapiがフレームワーク本体、uvicornがASGI対応のWebサーバーです。

最初のAPIを作る

main.pyというファイルを作成し、以下のコードを書きます。

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root():
    return {"message": "Hello API"}

たった5行でAPIが完成します。@app.get("/")はHTTPのGETメソッドでルートパス(/)にアクセスしたときにroot()関数を実行するという意味です。

サーバーの起動

uvicorn main:app --reload

--reloadオプションを付けると、コードを変更するたびに自動でサーバーが再起動します。開発中は常に付けておくと便利です。

起動後、ブラウザで http://127.0.0.1:8000/ にアクセスすると {"message":"Hello API"} が表示されます。

クライアント側からのアクセス

Pythonのrequestsライブラリを使ってAPIを呼び出す場合のコードです。

import requests

response = requests.get("http://127.0.0.1:8000/")
print(response.status_code)  # 200
print(response.text)         # {"message":"Hello API"}

パスパラメーター — URLの一部を変数にする

URLのパスに変数を埋め込みたい場合に使います。たとえば /items/111 のように、IDをURLに含めてアクセスするパターンです。

サーバー側

@app.get("/items/{item_id}")
def read_item(item_id):
    return {"item_id": item_id, "item_name": "Tシャツ"}

{item_id} の部分が変数になります。/items/111 にアクセスすると item_id"111" が代入されます。

クライアント側

response = requests.get("http://127.0.0.1:8000/items/111")
# {"item_id":"111","item_name":"Tシャツ"}

パス競合の注意点

以下のように固定パスと可変パスが競合する場合、コードの記述順で優先度が決まります

# この順番で書くこと(固定パスを先に定義)
@app.get("/items/special")    # 固定パス(先に定義)
def read_special():
    return {"item": "special"}

@app.get("/items/{item_id}")  # 可変パス(後に定義)
def read_item(item_id):
    return {"item_id": item_id}

順番を逆にすると、/items/special へのアクセスが可変パスのほうにマッチしてしまい、item_id="special" として処理されます。


クエリパラメーター — URLの末尾にフィルター条件を付ける

URLの末尾に ?key=value の形式でパラメーターを渡す方法です。一覧の絞り込みやページネーションで使います。

サーバー側

items = ["りんご", "バナナ", "みかん", "ぶどう", "いちご"]

@app.get("/items")
def read_items(skip: int = 0, limit: int = 10):
    return {"items": items[skip:skip+limit]}

デフォルト値を設定しておくと、パラメーターを省略してもエラーになりません。

クライアント側

# 2番目から2件取得
response = requests.get("http://127.0.0.1:8000/items?skip=1&limit=2")
# {"items":["バナナ","みかん"]}

バリデーション(値の検証)

Queryを使うと、受け取る値に制約を付けられます。

from typing import Annotated
from fastapi import Query

@app.get("/items")
def read_items(limit: Annotated[int, Query(ge=1, le=10)] = 10):
    # ge=1: 1以上のみ許可、le=10: 10以下のみ許可
    return {"items": items[:limit]}

範囲外の値が送られてきた場合、FastAPIが自動で422 Unprocessable Entityエラーを返します。自分でバリデーションコードを書く必要がありません。


リクエストボディ — POSTやPUTでデータを送る

GETではURLにパラメーターを付けましたが、POST/PUTではリクエストボディにJSON形式でデータを含めます。ユーザー登録や商品登録など、複雑なデータを送る場合に使います。

Pydanticモデルでデータ構造を定義する

from pydantic import BaseModel
from typing import Union

class Item(BaseModel):
    name: str
    price: float
    description: Union[str, None] = None

BaseModelを継承したクラスを作ると、FastAPIが受け取ったJSONデータを自動で型チェック・変換してくれます。descriptionは省略可能なフィールドです。

サーバー側

@app.post("/items")
def create_item(item: Item):
    print(f"受信データ: {item}")
    return item

クライアント側

response = requests.post(
    "http://127.0.0.1:8000/items",
    json={"name": "Tシャツ", "price": 2000, "description": "白Tシャツ"}
)

priceに文字列を送ると自動でエラーが返ります。型安全なAPIが追加コードなしで実現できます。


ヘッダー — 認証情報やメタデータを送受信する

APIキーやアクセストークンなど、URLには含めたくない情報はHTTPヘッダーに載せます。

リクエストヘッダーの受け取り

from fastapi import Header
from typing import Union

@app.get("/sample")
def read_sample(authorization: Union[str, None] = Header(default=None)):
    print(f"Authorization: {authorization}")
    return {"message": "認証情報を受信しました"}

クライアント側

response = requests.get(
    "http://127.0.0.1:8000/sample",
    headers={"Authorization": "Bearer token123"}
)

レスポンスヘッダーの設定

サーバーからクライアントにカスタムヘッダーを返すこともできます。

from fastapi import Response

@app.get("/sample")
def read_sample(response: Response):
    response.headers["X-Request-Id"] = "abc-123"
    return {"message": "カスタムヘッダー付きレスポンス"}

非同期処理 — 複数の処理を並行実行する

FastAPIはasync/awaitによる非同期処理に対応しています。外部APIの呼び出しやデータベースクエリなど、待ち時間が発生する処理を並行で実行できます。

サーバー側

import asyncio

@app.get("/sleep/{seconds}")
async def sleep_time(seconds: int):
    await asyncio.sleep(seconds)
    return {"waited": f"{seconds}秒"}

同期と非同期の速度差

2つのリクエスト(1秒待機 + 2秒待機)を同時に発行した場合の違いです。

方式 合計時間 理由
同期処理 約3秒 1秒待機 → 2秒待機を順番に実行
非同期処理 約2秒 両方を同時に開始、遅いほうに合わせて完了

データベースへの問い合わせが多いAPIサーバーでは、非同期処理による性能向上が顕著です。


自動ドキュメント生成 — FastAPI最大の強み

FastAPIでAPIを作ると、コードを書くだけでAPIドキュメントが自動生成されます。追加の設定は不要です。

URL ドキュメント形式 特徴
/docs Swagger UI ブラウザ上でAPIを試せるインタラクティブUI
/redoc ReDoc 閲覧用の見やすいドキュメント
/openapi.json OpenAPI仕様 他ツールとの連携用JSON

/docsにアクセスすると、定義したすべてのエンドポイントが一覧表示され、画面上から直接リクエストを送ってレスポンスを確認できます。フロントエンドエンジニアとの連携や、外部にAPIを公開する場合に特に便利です。


FastAPIが選ばれる理由

FastAPIをDjangoやFlaskと比較したとき、以下の点が優位です。

項目 FastAPI Django REST Framework Flask
非同期処理 ネイティブ対応 限定的 非対応(拡張が必要)
型チェック Pydanticで自動検証 シリアライザーで手動定義 なし
ドキュメント生成 自動 追加ライブラリ必要 追加ライブラリ必要
パフォーマンス 高速(ASGI) 中程度(WSGI) 中程度(WSGI)
学習コスト 低い 高い(機能が多い) 低い

Netflix、Uber、Microsoftなど大手企業でも本番環境で採用されており、GitHubスター数は80,000を超える人気フレームワークです。

「小〜中規模のAPIを素早く作りたい」「型安全なAPIを最小限のコードで実現したい」という場面でFastAPIは最適な選択肢です。


まとめ

FastAPIの基本的な使い方を整理します。

やりたいこと 使う機能
URL内の変数取得 パスパラメーター /items/{item_id}
検索・フィルター クエリパラメーター ?skip=0&limit=10
データ送信 リクエストボディ json={"name": "..."}
認証情報の送受信 ヘッダー Authorization: Bearer ...
並行処理 async/await await asyncio.sleep(1)
ドキュメント確認 自動生成 /docs にアクセス

FastAPIは「Pythonの型ヒントを活用して、APIの実装とドキュメントを同時に生成する」という設計思想のフレームワークです。まずはpip install fastapi uvicornして、5行のHello APIから始めてみてください。

このブログを書いている人

福岡のAIエンジニア。生成AI(ChatGPT・Claude)を活用した業務自動化、Webサイト開発、技術顧問を行っています。
「何から始めればいいかわからない」というご相談も歓迎です。

© 2022-2025 infoHiroki. All rights reserved.