👌

🚀 FastAPI 実践入門:第二歩目で学ぶルーティングとリクエスト処理

に公開

🔧 はじめに

この記事では、FastAPIを使ってWeb APIの開発を一歩進めたい人向けに、実用的なルーティング設計やフォームデータの受け取り、エラーハンドリングの基本を解説します。FastAPIの基礎(GET/POSTの使い方や型ヒント)を理解している方が対象です。第一歩目の記事では最小のAPIの構築とPydanticによる入力バリデーションを学びましたが、ここではそれを踏まえた応用を扱います。これにより、より現実的でスケーラブルなアプリケーション設計ができるようになります。

📌 複数ルーティングの設計

FastAPIでは、関数ごとにエンドポイントを分けることで、APIの構造を明確に保つことができます。さらに、関連機能ごとにエンドポイントを整理することで、開発や保守がしやすくなります。

from fastapi import FastAPI

app = FastAPI()

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

@app.get("/about")
def about():
    return {"description": "This is the second step with FastAPI."}

@app.get("/contact")
def contact():
    return {"email": "contact@example.com"}

URLに応じて異なる関数が実行され、ルーティングが整理されていきます。また、ルーティングを関数名や役割ごとにグループ化して管理することで、コードの見通しも良くなります。

📝 リクエストボディのバリデーション強化

pydanticのモデルを活用することで、より厳密な入力チェックが可能です。バリデーションエラーが発生した場合、自動的にエラーメッセージが返されるため、セキュリティと開発効率の両面でメリットがあります。

from pydantic import BaseModel, Field

class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=20)
    age: int = Field(..., gt=0, lt=150)
    email: str

min_lengthgt(greater than)、lt(less than)で制約条件を定義できるほか、regexdefault_factoryなどを使えばさらに細かい条件も指定できます。

@app.post("/register")
def register(user: User):
    return {"message": f"Welcome, {user.username}!"}

このようにすることで、正しい形式のリクエストだけが通過し、バグや不正なデータの混入を防ぐことができます。

🔄 フォームデータの受け取り

FastAPIでは、Formを使うことでHTMLフォームのデータも簡単に受け取れます。Formを使うことで、クライアント側がJSONではなくapplication/x-www-form-urlencoded形式で送るデータにも対応可能です。

from fastapi import Form

@app.post("/login")
def login(username: str = Form(...), password: str = Form(...)):
    # 実際の認証処理がここに入る
    return {"username": username, "status": "Login attempted"}

また、フォーム入力の受け取りにDependsRequestと組み合わせることで、より柔軟な処理も可能になります。
HTMLフォーム例:

<form action="/login" method="post">
    <label>ユーザー名:</label>
    <input type="text" name="username">
    <label>パスワード:</label>
    <input type="password" name="password">
    <input type="submit" value="ログイン">
</form>

🚨 エラーハンドリング

API開発では、ユーザーの入力や外部システムとの通信エラーなど、さまざまなエラーが発生します。FastAPIでは、HTTPException を使うことで簡単にエラーを返すことができます。

from fastapi import HTTPException

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id > 100:
        raise HTTPException(status_code=404, detail="Item not found")
    return {"item_id": item_id}

また、グローバルなエラーハンドラーを定義することで、特定の例外をカスタマイズして処理することもできます。

from fastapi.responses import JSONResponse
from fastapi.requests import Request
from fastapi.exception_handlers import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    return JSONResponse(
        status_code=422,
        content={"message": "入力に誤りがあります。", "details": exc.errors()}
    )

🎯 まとめ

  • 複数エンドポイントの設計でアプリ構成を整理し、可読性・保守性を向上
  • pydanticを用いた入力バリデーションで信頼性の高いAPI設計
  • HTMLフォームとの連携により、Webアプリとの接続もスムーズ
  • エラーハンドリングでユーザーフレンドリーなレスポンスを実現

FastAPIの柔軟な機能を活用すれば、シンプルなAPIから複雑なWebシステムまで対応できます。


株式会社ONE WEDGE

【Serverlessで世の中をもっと楽しく】 ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
https://onewedge.co.jp/

Discussion