---
title: "FastAPIとは？最短の起動手順とasync/defの使い分け、0.162の変更点"
url: "https://www.issoh.co.jp/tech/details/3859/"
published: 2024-10-16
updated: 2026-10-28
categories: ["Python"]
publisher: "株式会社一創"
---

# FastAPIとは？最短の起動手順とasync/defの使い分け、0.162の変更点

FastAPIは、Pythonの型ヒントをそのままAPIの仕様として使うWebフレームワークです。関数の引数に `item_id: int` と書くだけで、型変換・入力検証・エラーレスポンス・OpenAPIドキュメントがまとめて手に入ります。公式チュートリアルの起動手順は `uvicorn main:app --reload` から `fastapi dev` に変わっており、2026年10月28日に「fastapi」の検索上位から取得した日本語の解説記事5本のうち、4本は `uvicorn main:app` による旧手順のままで、`fastapi dev` を使う記事はありませんでした。この記事は2026年10月23日公開の最新版0.162.0をPython 3.12の仮想環境で動かした結果をもとに、最短の起動手順、`async def` と `def` の使い分け、そして0.140以降に変わった挙動を整理します。

## まとめ：FastAPIの要点（0.162.0時点）

- **正体**：HTTPの処理はStarlette、データ検証はPydanticが担い、FastAPIは両者を型ヒントでつなぐ層です。ORMや管理画面は持ちません。ライセンスはMITで、商用利用もできます。
- **要件**：最新版は0.162.0。Python 3.10以上が必須で、Python 3.9の環境ではエラーにならず、古い0.128.8が選ばれます。
- **起動**：`pip install "fastapi[standard]"` の後、開発は `fastapi dev`、本番は `fastapi run` を使います。dev は127.0.0.1で自動リロード付き、run は0.0.0.0でリロードなしです。
- **非同期**：`async def` の中でブロッキングI/Oや長時間の同期処理を直接実行すると、そのワーカーのイベントループが止まります。0.5秒の同期処理を10件同時に送ると、`async def` では6.0秒、`def` では0.7秒でした。迷ったら `def` で書きます。
- **版の変化**：0.151.0からJSONの `null` を既定値で置き換えなくなり、0.155.0では `Query(custom=...)` が `TypeError` になりました。2026年7月以前に書かれたコードは、更新前にこの2点を確認してください。
- **選び分け**：管理画面・認証・ORMが最初から要るならDjangoを選びます。JSONを返すAPIサーバー単体ならFastAPIが向いています。

## FastAPIとは：型ヒントをAPIの仕様にするPythonフレームワーク

FastAPIはSebastián Ramírez氏が開発するPython製のWebフレームワークです。[公式ドキュメント](https://fastapi.tiangolo.com/)の依存関係の節は「FastAPI depends on Pydantic and Starlette.」と書いており、HTTPの処理をStarletteに、値の検証と変換をPydanticに任せています。FastAPI自身が受け持つのは、関数の型ヒントを読み取って両者をつなぎ、OpenAPIスキーマを生成する部分です。土台のStarletteで見つかった脆弱性はFastAPIのアプリにも影響します。版の確かめ方は[Starletteの脆弱性CVE-2026-48710とは｜Hostヘッダで認可を迂回される条件と修正手順](/tech/details/18235/)で扱っています。

「速い」と言われる根拠として公式が挙げるのは第三者ベンチマークのTechEmpowerで、Uvicorn上のFastAPIより上にいるのは内部で使っているStarletteとUvicornだけです。実際の応答時間は、アプリの処理内容やASGIサーバー、イベントループの実装に左右されます。Uvicornが使うuvloopはWindowsでは動かないため、Windowsでは標準のasyncioで動きます。

### 型ヒントから得られる入力検証とAPIドキュメント

型ヒントを付けた関数定義から、入力の型変換・検証とAPIドキュメントを生成できます。

| 得られるもの                       | 元になる記述                  |
| ---------------------------- | ----------------------- |
| リクエストの型変換                    | 引数の型ヒント（`item_id: int`） |
| 入力検証と422応答                   | Pydanticモデル・型ヒント        |
| OpenAPIスキーマ（`/openapi.json`） | 関数シグネチャ全体               |
| 対話型ドキュメント（`/docs`・`/redoc`）  | OpenAPIスキーマ             |

典型的な用途は、REST APIやマイクロサービスのバックエンド、機械学習モデルの推論エンドポイント、SPAから呼ぶAPIサーバーです。サーバー側でHTMLを組み立てる用途にもJinja2テンプレートで対応でき、HTMLを返すルートでも入力の型変換・検証は働きます。`response_class=HTMLResponse` を指定したルートに `/p/x` のような不正な値を送ると422が返り、OpenAPIにも `text/html` の応答として記載されます。管理画面やORMまで必要なら、Djangoを比較対象に入れます。

### 最新版と動作要件（2026年10月時点）

| 項目         | 値                   |
| ---------- | ------------------- |
| FastAPI最新版 | 0.162.0（2026-10-23） |
| 必要なPython  | 3.10以上              |
| Starlette  | 0.46.0以上（最新1.10.0）  |
| Pydantic   | 2.9.0以上（最新2.14.1）   |
| ライセンス      | MIT                 |

値は[PyPIのfastapiのページ](https://pypi.org/project/fastapi/)で確認したものです。Python 3.9のサポートは0.129.0（2026-02-12）で終わりました。注意したいのは、Python 3.9の環境で `pip install fastapi` を実行してもエラーにならない点です。Python 3.9の仮想環境で実行すると、Python 3.9に対応する最後の版である0.128.8が選ばれます。通常のpip出力には選択・インストールされた版が表示されるため、その表示も確認してください。記事のコードが動かないときは、まず `python -c "import fastapi; print(fastapi.__version__)"` で実際に入った版を確かめてください。

Pydanticはv2系が前提です。v1系の `@validator` や `parse_obj()` はv2でも非推奨APIとして残っており、警告付きで動く場合があります。新規コードでは、それぞれ `@field_validator` と `model_validate()` を使います。v1との違いは[Pydanticとは？読み方・BaseModelの使い方とV1との違い【2.13対応】](/tech/details/4838/)で整理しています。

## FastAPIのインストールと開発サーバーの起動

### pip install “fastapi\[standard\]” と3通りの入れ方

仮想環境を有効にしてから、標準の依存関係込みでインストールします。公式ドキュメントは `uv add "fastapi[standard]"` の形で書いていますが、pipでも同じです。

```
pip install "fastapi[standard]"
```

引用符は省略できません。zshでは角括弧がファイル名のパターンとして解釈されるため、囲まないとインストールが失敗します。

入れ方は3通りあり、入るものが大きく違います。次の表は、Python 3.12の空の仮想環境にFastAPI 0.162.0を入れた際のパッケージ数です。OSや依存パッケージの更新によって個数は変わるため、固定の内訳ではありません。

| 指定                                       | パッケージ数 | fastapiコマンド | Uvicorn |
| ---------------------------------------- | ------ | ----------- | ------- |
| `fastapi`                                | 11     | 起動には追加依存が必要 | なし      |
| `fastapi[standard-no-fastapi-cloud-cli]` | 53     | あり          | あり      |
| `fastapi[standard]`                      | 59     | あり          | あり      |

`standard` には、Uvicorn・httpx・Jinja2・python-multipartに加えて、0.142.0で追加された標準のOpenTelemetry対応のためのopentelemetry-sdkとエクスポーターが入ります。さらに `fastapi-cli[standard]` を経由して、商用のデプロイ先FastAPI Cloud向けの `fastapi-cloud-cli` と、それが依存する `sentry-sdk` も入ります。本番のコンテナイメージに外部サービス向けのCLIを含めたくないなら、`fastapi[standard-no-fastapi-cloud-cli]` を指定すれば差分の6個が入りません。素の `fastapi` だけではUvicornが入らず、fastapiコマンドによる起動にも追加依存が必要です。直接起動する場合はUvicornを別に入れます。

### main.pyの最小コードとfastapi devによる起動

`main.py` を作ります。

```
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}
```

同じディレクトリで起動します。ファイル名の指定は不要です。

```
fastapi dev
```

fastapi-cli 0.0.32で実行すると、次の行が表示されました。`main.py` から `app` を見つけ、自動リロード付きのUvicornを起動しています。

```
 🐍 Using import string: main:app (auto-discovered, use --verbose to learn more)
 🌐 Server started at http://127.0.0.1:8000
    Documentation at http://127.0.0.1:8000/docs
INFO:     Will watch for changes in these directories: ['/private/tmp/v3859/app']
INFO:     Started reloader process [76282] using WatchFiles
```

`http://127.0.0.1:8000/items/5?q=somequery` を開くと `{"item_id": 5, "q": "somequery"}` が返り、`/docs` にSwagger UI、`/redoc` にReDocが表示されます。`main.py` 以外の名前にする場合や、プロジェクトに複数のアプリがある場合は、起動ログが案内するとおり `pyproject.toml` に `[tool.fastapi]` と `entrypoint = "main:app"` を書いておけば毎回の指定が要らなくなります。

以前から使われてきた `uvicorn main:app --reload` も今も動きます。[公式チュートリアル](https://fastapi.tiangolo.com/tutorial/first-steps/)の標準手順が `fastapi dev` に変わっただけで、Uvicornのオプションを細かく指定したい場合や、プロセス管理を別のツールに任せる場合は直接起動で構いません。Uvicorn自体の設定は[Uvicornとは？読み方・Gunicornとの違いと起動・本番設定【0.54対応】](/tech/details/4843/)で解説しています。

### fastapi dev と fastapi run の違い

2つのコマンドは同じUvicornを起動しますが、既定値が開発用と本番用に分かれています。両方を起動したときの表示と既定値は次のとおりです。

| 項目       | fastapi dev        | fastapi run     |
| -------- | ------------------ | --------------- |
| 起動時の表示   | development mode   | production mode |
| 待ち受けアドレス | 127.0.0.1（自分のPCだけ） | 0.0.0.0（外部から届く） |
| 自動リロード   | 有効                 | 無効              |
| 複数プロセス   | 使わない               | `--workers` で指定 |

`fastapi dev` のままコンテナに入れると、127.0.0.1でしか待ち受けないため、コンテナの外からは接続できません。本番では `fastapi run` を使うか、Uvicornをリロードなしで直接起動します。開発用Dockerでは `fastapi dev --host 0.0.0.0` も使えます。リバースプロキシの下のパスで公開する場合は、0.146.0で非推奨になった `FastAPI(root_path=...)` の代わりに `fastapi run --root-path /api/v1` を指定します。

## パラメータとリクエストボディの書き方

### パスパラメータとクエリパラメータの振り分け

上のコードでは、`item_id` はURLパスの `{item_id}` と同じ名前なのでパスパラメータになり、パスに現れない `q` はクエリパラメータになります。どちらに置くかを書き分ける必要はありません。

型ヒントは変換のルールでもあります。`/items/5` の `"5"` は整数の5に変換され、`/items/abc` を開くと次のJSONとともにHTTP 422が返りました。どの引数が不正なのかが `loc` に入るため、エラー処理を自分で書く必要はありません。

```
{"detail": [{"type": "int_parsing", "loc": ["path", "item_id"],
  "msg": "Input should be a valid integer, unable to parse string as an integer",
  "input": "abc"}]}
```

### Pydanticモデルによるリクエストボディの検証

POSTで受け取るJSONは、Pydanticモデルを引数の型にするだけで検証されます。

```
from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float = Field(gt=0)
    tax: float | None = None


@app.post("/items/")
def create_item(item: Item):
    total = item.price + (item.tax or 0)
    return {"name": item.name, "total": total}
```

`{"name": "a", "price": 0}` を送ると、`greater_than` の422で弾かれ、関数の中には入りません。`{"name": "a", "price": 100, "tax": 10}` なら `{"name": "a", "total": 110.0}` が返ります。このモデルはそのまま `/docs` のリクエストボディ定義にもなるため、型の定義・検証・ドキュメントを1か所で管理できます。

### エラー応答・起動時の処理・バックグラウンド処理

実際のAPIでよく使う3つの機能を1つにまとめた例です。見つからないときに404を返す `HTTPException`、各ワーカーのアプリ起動時と終了時に実行される `lifespan`、レスポンスを返した後に処理を続ける `BackgroundTasks` を使っています。

```
from contextlib import asynccontextmanager

from fastapi import BackgroundTasks, FastAPI, HTTPException

fake_db: dict[int, str] = {}


@asynccontextmanager
async def lifespan(app: FastAPI):
    fake_db[1] = "alice"  # ワーカーごとに起動時に1回（DB接続の確立など）
    yield
    fake_db.clear()  # ワーカーごとに終了時に1回（接続のクローズなど）


app = FastAPI(lifespan=lifespan)


def write_log(message: str):
    with open("access.log", "a") as f:
        f.write(message + "\n")


@app.get("/users/{user_id}")
def read_user(user_id: int, background_tasks: BackgroundTasks):
    if user_id not in fake_db:
        raise HTTPException(status_code=404, detail="User not found")
    background_tasks.add_task(write_log, f"read {user_id}")
    return {"user_id": user_id, "name": fake_db[user_id]}
```

TestClientで確かめると、`/users/1` は200で `{"user_id": 1, "name": "alice"}`、`/users/2` は404で `{"detail": "User not found"}` を返し、`access.log` には `read 1` の1行だけが書かれました。古い記事にある `@app.on_event("startup")` は非推奨なので、新しく書くなら `lifespan` を使います。`BackgroundTasks` は同じプロセスの中で動くため、数分かかる処理や失敗時の再実行が必要な処理には向きません。その場合はCeleryなどのタスクキューに任せます。

ファイルが増えてきたら `APIRouter` でルーターを分けて `app.include_router()` でまとめ、ブラウザのSPAから呼ぶなら `CORSMiddleware` を登録します。`APIRouter` は `fastapi` から、`CORSMiddleware` は `fastapi.middleware.cors` からimportします。追加のインストールは要りません。ディレクトリ構成の決め方は[FastAPIのベストプラクティス｜ディレクトリ構成・SQLAlchemy 2.1の設計・テストを実測で解説](/tech/details/4347/)で扱っています。

## async def と def の使い分け：迷ったら def

同期I/Oを呼ぶ場所は、FastAPIの並行処理性能を左右します。「FastAPIは非同期だから `async def` で書く」という理解は誤りで、場所を間違えるとかえって遅くなります。[公式のasyncの解説](https://fastapi.tiangolo.com/async/)は、await できないライブラリ（多くのDBライブラリがこれに当たる）を使うなら普通の `def` で書き、判断がつかないときも `def` を使うよう勧めています。

| 関数の中身             | 宣言        | 実行される場所   |
| ----------------- | --------- | --------- |
| await で呼ぶ非同期ライブラリ | async def | イベントループ   |
| await できない同期ライブラリ | def       | 外部スレッドプール |
| どこにも通信しない軽い計算     | async def | イベントループ   |
| 判断がつかない           | def       | 外部スレッドプール |

差がどれくらい出るかを確かめるため、0.5秒の待ちを入れた3つのエンドポイントを `fastapi run`（ワーカー1つ）で起動し、httpxの非同期クライアントから10件を同時に送りました。各エンドポイントに10件を `asyncio.gather` で送り、全応答が返るまでを `time.perf_counter` で測っています。環境はmacOS 26.6.2・Intel Core i9-9880H・Python 3.12・Uvicorn 0.54.0・httpx 0.28.1で、2回実行した結果が後の表です。

```
import asyncio
import time

from fastapi import FastAPI

app = FastAPI()


@app.get("/bad")
async def bad():
    time.sleep(0.5)  # 同期の待ちを async def の中で呼ぶ
    return {"ok": True}


@app.get("/good")
def good():
    time.sleep(0.5)  # def ならスレッドプールで動く
    return {"ok": True}


@app.get("/best")
async def best():
    await asyncio.sleep(0.5)  # 非同期の待ちを await する
    return {"ok": True}
```

送信側のスクリプトは次のとおりです。

```
import asyncio
import time

import httpx


async def main():
    async with httpx.AsyncClient(timeout=60) as c:
        for path in ["/bad", "/good", "/best"]:
            t = time.perf_counter()
            await asyncio.gather(
                *[c.get(f"http://127.0.0.1:8000{path}") for _ in range(10)]
            )
            print(path, f"{time.perf_counter() - t:.2f}s")


asyncio.run(main())
```

| エンドポイント                | 1回目   | 2回目   |
| ---------------------- | ----- | ----- |
| /bad（async def＋同期の待ち）  | 6.43秒 | 6.03秒 |
| /good（def＋同期の待ち）       | 0.75秒 | 0.72秒 |
| /best（async def＋await） | 0.60秒 | 0.59秒 |

`/bad` では、`time.sleep()` がイベントループを止めている間ほかのリクエストが一切進まず、10件が1件ずつ順に処理されました。`/good` は同じ同期処理でも、FastAPIが `def` の関数を外部スレッドプールで動かすため並行に進みます。psycopg2での問い合わせや `requests.get()` を `async def` の中に書くと、`/bad` と同じことが起きます。

スレッドプールにも上限はあります。AnyIOの既定は40で、0.162.0の環境で `anyio.to_thread.current_default_thread_limiter().total_tokens` を表示しても40です。数秒かかる同期処理を大量に `def` で流すとプールが埋まり、後のリクエストが待たされます。重いCPU処理は `async def` に置いても同じくイベントループを止めるので、別のワーカーやタスクキューに逃がしてください。この規則は依存関係（`Depends`）にもそのまま当てはまり、同期のDBセッションを返す依存は `def` で書きます。

## 0.140〜0.162で変わった挙動：古いコードが動かなくなる箇所

FastAPIは2026年7月の0.139.0から10月23日の0.162.0まで、3か月あまりで60本のリリースを重ねました。0.x系のため、マイナー番号の更新でも動作が変わります。[リリースノート](https://fastapi.tiangolo.com/release-notes/)で「Breaking Changes」とされたもののうち、アプリの応答が変わるものを、0.139.0・0.150.0・0.162.0の3つの版で同じコードを動かして比べました。

| 変更が入った版         | 書き方                        | 0.139.0   | 0.162.0                |
| --------------- | -------------------------- | --------- | ---------------------- |
| 0.151.0         | Body()に既定値10、JSONでnullを送る  | 200・10に置換 | 422                    |
| 0.155.0         | Query(custom=”v”)          | 動く        | TypeError              |
| 0.146.0         | FastAPI(root\_path=”/api”) | 動く        | 非推奨の警告                 |
| 0.147.0→0.162.0 | 必須のbool型フォームを省略            | 422       | 422（0.150.0は200・False） |

最も気づきにくいのは1行目です。`limit: Annotated[int, Body()] = 10` と `note: Annotated[str | None, Body()] = "x"` を受け取るエンドポイントに `{"limit": null, "note": null}` を送ると、0.139.0と0.150.0はエラーを出さずに `{"limit": 10, "note": "x"}` を返しました。送られた `null` が既定値に置き換わっていたということです。0.162.0では `limit` が `int_type` の422になり、`note` は `None` として受け取られます。「値を消したい」という意味で `null` を送るクライアントがある場合、更新の前後で保存される値が変わります。

2行目は、型に関係しない独自の値をドキュメントに出すためのキーワード引数が0.155.0で削除されたものです。`Query(json_schema_extra={"custom": "v"})` に書き換えます。4行目のHTMLフォームのチェックボックスは、0.147.0で「省略されたらFalse」に変わり、0.162.0で元の挙動に戻りました。`agree: Annotated[bool, Form()] = False` のように既定値Falseを明示しておけば、どの版でも同じ結果になります。

このほか、0.142.0でOpenTelemetryに標準で対応し、0.143.0からは `OTEL_*` 環境変数によるエクスポーターの自動設定に `FASTAPI_OTEL_AUTO_CONFIGURE=true` が必要になりました。0.139.0以前から更新する場合は、版を1つに固定したうえでテストを通してから上げてください。`fastapi>=0.100` のような下限だけの指定は、上の変更を知らないうちに取り込みます。

## FlaskやDjangoとの違いと、FastAPIを選ぶべきでない場面

判断の軸は、作るものがAPIだけかどうかです。FastAPIを除いたDjangoとFlaskの比較は[DjangoとFlaskの違い｜内蔵範囲・非同期・案件規模から選ぶ判断基準](/tech/details/17084/)で扱っています。

| 観点        | FastAPI      | Flask     | Django    |
| --------- | ------------ | --------- | --------- |
| 主な用途      | API（JSON）    | 小規模なWeb全般 | フルスタックWeb |
| 入力検証      | 標準（Pydantic） | 拡張で追加     | Forms・DRF |
| APIドキュメント | 自動生成         | 拡張で追加     | DRFで追加    |
| ORM       | なし           | なし        | あり        |
| 管理画面      | なし           | なし        | あり        |
| 非同期       | ASGIで標準      | 一部対応      | 一部対応      |

FastAPIを選ぶべきでないのは、管理画面・ユーザー認証・ORM・マイグレーションが最初から必要な業務システムです。FastAPIでこれらをそろえると、SQLAlchemy・Alembic・認証ライブラリを1つずつ選んで接続することになり、Djangoが最初から持っているものを作り直す形になります。サーバー側でHTMLを組み立て、管理画面やORMも必要なWebサイトでは、それらを標準搭載するDjangoを優先して検討します。

逆に、Flaskで作ったAPIに手書きの入力チェックとSwaggerの定義がたまっているなら、移行する価値があります。どちらもデコレータでルートを書く構造なので、`@app.route("/x", methods=["POST"])` を `@app.post("/x")` に、手書きのチェックをPydanticモデルに置き換える作業が中心です。HTMLテンプレートを返す画面が中心のFlaskアプリは、移行しても得るものはほとんどありません。TypeScriptのHonoと比べる場合は[Hono vs FastAPI（Python）の違い｜Honoとは・メリット・使い方を実行結果で比較【Hono 4.13】](/column/details/3001/)が参考になります。

## 本番環境で踏みやすい落とし穴

### 既定で公開される /docs と /openapi.json

Swagger UIとOpenAPIスキーマは既定で誰でも見られる状態で公開されます。社内向けのAPIでも、`/openapi.json` を開けば全エンドポイントの仕様が読めます。本番では `FastAPI(docs_url=None, redoc_url=None, openapi_url=None)` で無効にするか、認証の内側に置きます。`docs_url=None` だけでは画面が消えるだけで、`/openapi.json` は200のまま残ります。手順は[FastAPIのSwagger UI（/docs）の使い方｜表示・設定・本番で隠す手順【2026年版】](/tech/details/2246/)で解説しています。

### fastapi run のワーカー数とコンテナ

複数のCPUコアを使うには、ワーカー数を指定します。

```
fastapi run --workers 4 main.py
```

ただしKubernetesのようにコンテナを複数並べる環境では、[公式のDockerの解説](https://fastapi.tiangolo.com/deployment/docker/)はワーカーを使わず、コンテナごとにUvicornのプロセスを1つだけ動かす構成を勧めています。プロセスの数はコンテナの数で調整し、1つのコンテナの中で二重に増やさないという考え方です。Dockerfileの書き方は[FastAPI×ReactのDocker本番デプロイ｜uv対応Dockerfileとcompose構成](/tech/details/2980/)にまとめています。サーバーを持たずに動かす選択肢としては、[Cloudflare Python Workersとは？FastAPIをエッジで動かす手順とパッケージ制約【2026年10月時点】](/tech/details/18259/)もあります。

### DB・フロントエンド接続の実装範囲

FastAPIはORMを持たないため、データベースにはSQLAlchemyなどを組み合わせます。同期のSQLAlchemyを使うなら、前の章のとおりパス関数と依存は `def` で書きます。Reactなどのフロントエンドと組み合わせる場合のCORSと開発用プロキシの設定は[React×FastAPI連携の手順｜CORS・Viteプロキシ・型生成とDocker Composeで動かす【2026年版】](/tech/details/2242/)で扱っています。既存システムとのつなぎ込みまで含めて外部に任せたい場合は、一創の[API開発・システム連携](/service/system/api/)で相談を受け付けています。

## よくある質問

### FastAPIとREST APIの違いは何ですか？

REST APIはHTTPでやり取りするAPIの設計スタイルの名前で、FastAPIはREST APIをPythonで作るためのフレームワークです。比べる対象ではなく、FastAPIでREST APIを作るという関係です。

### FastAPIのライセンスは何ですか？商用利用できますか？

MITライセンスです。商用のサービスに組み込むことも、ソースを公開せずに使うこともできます。著作権表示とライセンス文を残す義務はあります。土台のPydanticはMIT、StarletteはBSD-3-Clauseで、どちらも商用利用を妨げない許諾型のライセンスです。

### fastapi dev と uvicorn main:app –reload のどちらを使えばよいですか？

開発中は公式の標準である `fastapi dev` を使います。中身は自動リロード付きのUvicornなので、`uvicorn main:app --reload` でも同じように動きます。Uvicornのオプションを細かく指定したいときだけ直接起動を選びます。

### FastAPIのパス関数はすべて async def で書く必要がありますか？

必要ありません。await できないライブラリ（多くの同期DBドライバ）を使う関数は `def` で書きます。`async def` の中で同期処理を呼ぶと、10件同時のリクエストで `def` の8倍以上の時間がかかりました。

### FastAPIに脆弱性はありますか？

FastAPI本体に加えて、土台のStarletteの脆弱性もFastAPIのアプリに影響します。2026年には、不正なHostヘッダにより、request.url.pathを使う認可チェックを迂回されるCVE-2026-48710が公表されました。`pip show starlette` で実際に入っている版を確かめ、修正版まで上げてください。条件と修正版は[Starletteの脆弱性CVE-2026-48710とは｜Hostヘッダで認可を迂回される条件と修正手順](/tech/details/18235/)で整理しています。

## 関連記事

- [FastAPIのSwagger UI（/docs）の使い方｜表示・設定・本番で隠す手順【2026年版】](/tech/details/2246/)
- [FastAPIのベストプラクティス｜ディレクトリ構成・SQLAlchemy 2.1の設計・テストを実測で解説](/tech/details/4347/)
- [React×FastAPI連携の手順｜CORS・Viteプロキシ・型生成とDocker Composeで動かす【2026年版】](/tech/details/2242/)
- [FastAPI×ReactのDocker本番デプロイ｜uv対応Dockerfileとcompose構成](/tech/details/2980/)
- [Uvicornとは？読み方・Gunicornとの違いと起動・本番設定【0.54対応】](/tech/details/4843/)

---

出典: [FastAPIとは？最短の起動手順とasync/defの使い分け、0.162の変更点](<https://www.issoh.co.jp/tech/details/3859/>)（株式会社一創）
