nextjs-fastapi-conventions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Next.js + FastAPI Conventions

Next.js + FastAPI 开发规范

Single source of truth for architecture, code quality, and testing in Next.js + FastAPI full-stack projects.
是Next.js + FastAPI全栈项目中架构设计、代码质量、测试相关规则的唯一权威参考。

Project Stack

技术栈

  • Frontend: Next.js 16 (App Router) + React 19 + shadcn/ui + Tailwind CSS v4 (TypeScript, in
    frontend/
    )
  • Backend: FastAPI + Uvicorn + Pydantic (Python 3.11+, in
    backend/
    )
  • 前端: Next.js 16 (App Router) + React 19 + shadcn/ui + Tailwind CSS v4 (TypeScript,存放于
    frontend/
    目录)
  • 后端: FastAPI + Uvicorn + Pydantic (Python 3.11+,存放于
    backend/
    目录)

Architecture

架构设计

BFF Pattern

BFF模式

The browser NEVER calls FastAPI directly. All backend communication flows through the Next.js server layer:
  • Server Actions (
    app/actions.ts
    ) handle mutations. Client components call these; they run on the Next.js server and proxy to FastAPI.
  • API Routes (
    app/api/*/route.ts
    ) exist ONLY for external consumers (health checks, webhooks), NOT for frontend use.
浏览器永远不会直接调用FastAPI接口,所有后端通信都需要经过Next.js服务层流转:
  • Server Actions
    app/actions.ts
    )处理变更操作,客户端组件调用这些方法,它们在Next.js服务端运行并代理请求到FastAPI。
  • API Routes
    app/api/*/route.ts
    )仅提供给外部调用方使用(健康检查、webhook),不供前端内部调用。

Type Safety (Zod Contracts)

类型安全(Zod契约)

Every FastAPI response is validated on the frontend with Zod:
  • lib/contracts.ts
    : Zod schemas mirroring Pydantic models.
  • lib/backend-client.ts
    :
    backendJson()
    fetches + validates against Zod.
  • Contract breaks fail fast with
    BackendRequestError
    .
New endpoint checklist:
  1. Pydantic response model in
    backend/api/schemas.py
    .
  2. Matching Zod schema in
    frontend/lib/contracts.ts
    .
  3. Contract test in
    frontend/tests/contracts.test.ts
    .
  4. backendJson()
    with schema in Server Action.
所有FastAPI返回的响应都会在前端通过Zod进行校验:
  • lib/contracts.ts
    :定义与Pydantic模型一一对应的Zod schema。
  • lib/backend-client.ts
    backendJson()
    方法负责发起请求并按照Zod schema校验返回结果。
  • 契约不匹配时会快速抛出
    BackendRequestError
    错误。
新增接口检查清单:
  1. backend/api/schemas.py
    中定义Pydantic响应模型。
  2. frontend/lib/contracts.ts
    中定义匹配的Zod schema。
  3. frontend/tests/contracts.test.ts
    中添加契约测试。
  4. 在Server Action中使用带schema校验的
    backendJson()
    方法。

Components

组件

  • Server Components (default): fetch data, pass as props.
  • Client Components (
    'use client'
    ): interactivity, browser APIs, hooks.
  • Server Components(默认):负责拉取数据,通过props传递给子组件。
  • Client Components(标注
    'use client'
    ):负责交互逻辑、调用浏览器API、使用hooks。

React 19

React 19

  • useActionState
    (NOT deprecated
    useFormState
    ).
  • Explicit state types (e.g.
    GreetingState
    in
    lib/greeting-state.ts
    ).
  • 使用
    useActionState
    (不要使用已废弃的
    useFormState
    )。
  • 显式定义状态类型(例如
    lib/greeting-state.ts
    中的
    GreetingState
    )。

Backend Structure

后端结构

  • Lifespan via
    @asynccontextmanager
    (NOT
    @app.on_event
    ).
  • pydantic-settings
    for typed config from env vars.
  • Versioned routers under
    api/v1/
    .
  • Every endpoint declares
    response_model
    and returns a Pydantic model.
  • 使用
    @asynccontextmanager
    定义生命周期(不要使用
    @app.on_event
    )。
  • 使用
    pydantic-settings
    从环境变量中读取带类型的配置。
  • 版本化路由统一存放于
    api/v1/
    目录下。
  • 每个接口都要声明
    response_model
    并返回Pydantic模型实例。

Code Quality

代码质量

Python

Python

  • Async endpoints,
    httpx.AsyncClient
    (not
    requests
    ).
  • Type hints everywhere.
    Annotated
    for FastAPI params.
  • Docstrings on modules, classes, public functions.
  • HTTPException
    for API errors. No swallowed exceptions.
  • Import grouping: stdlib | third-party | local.
  • 异步接口使用
    httpx.AsyncClient
    (不要使用
    requests
    )。
  • 所有位置都要添加类型注解,FastAPI参数使用
    Annotated
    声明。
  • 模块、类、公共函数都需要添加文档字符串。
  • API错误使用
    HTTPException
    抛出,不要吞掉异常。
  • 导入分组顺序:标准库 | 第三方依赖 | 本地模块。

TypeScript

TypeScript

  • strict: true
    . Never
    any
    (prefer
    unknown
    + narrowing).
  • Zod for all external data; derive types with
    z.infer<>
    .
  • Server Actions:
    'use server'
    , return typed state objects.
  • shadcn/ui components from
    components/ui/
    .
  • Import grouping: React/Next.js | third-party | local
    @/
    (components > lib > types).
  • Tailwind v4 semantic tokens (
    text-foreground
    ,
    bg-muted
    ), not raw colours.
  • 开启
    strict: true
    ,禁止使用
    any
    (优先使用
    unknown
    +类型收窄)。
  • 所有外部数据都用Zod校验,通过
    z.infer<>
    推导类型。
  • Server Action标注
    'use server'
    ,返回带类型的状态对象。
  • shadcn/ui组件从
    components/ui/
    导入。
  • 导入分组顺序:React/Next.js | 第三方依赖 | 本地
    @/
    模块(组件 > 工具库 > 类型定义)。
  • 使用Tailwind v4语义化token(
    text-foreground
    bg-muted
    ),不要直接写原始色值。

Styling

样式规范

  • Tailwind utility classes in JSX.
    cn()
    from
    lib/utils.ts
    for conditional classes.
  • Semantic tokens from
    @theme
    , not raw colour values.
  • Mobile-first responsive (
    sm:
    ,
    md:
    ,
    lg:
    ).
  • CVA for component variants. Sonner for toasts. next-themes for theme switching.
  • JSX中使用Tailwind工具类,条件类使用
    lib/utils.ts
    导出的
    cn()
    方法处理。
  • 使用
    @theme
    提供的语义化token,不要直接写原始色值。
  • 采用移动端优先的响应式设计(
    sm:
    md:
    lg:
    )。
  • 组件变体使用CVA定义,toast使用Sonner实现,主题切换使用next-themes。

File Organisation

文件组织

  • Pages in
    app/
    (App Router). Reusable components in
    components/
    .
  • shadcn/ui in
    components/ui/
    (don't edit directly).
  • Shared utils/types in
    lib/
    . Import via
    @/
    .
  • 页面存放于
    app/
    目录(App Router模式),可复用组件存放于
    components/
    目录。
  • shadcn/ui组件存放于
    components/ui/
    目录,不要直接修改。
  • 共享工具/类型存放于
    lib/
    目录,通过
    @/
    别名导入。

Testing

测试

Backend (pytest)

后端(pytest)

  • pytest
    +
    pytest-asyncio
    (auto mode).
  • httpx.AsyncClient
    +
    ASGITransport
    against FastAPI
    app
    .
  • Assert status codes AND JSON payloads.
  • @pytest.mark.anyio
    for async tests.
  • 使用
    pytest
    +
    pytest-asyncio
    (自动模式)。
  • 使用
    httpx.AsyncClient
    +
    ASGITransport
    对接FastAPI
    app
    实例测试。
  • 同时断言状态码和JSON返回值。
  • 异步测试添加
    @pytest.mark.anyio
    装饰器。

Frontend (Vitest)

前端(Vitest)

  • environment: 'node'
    . Tests in
    frontend/tests/*.test.ts
    .
  • Contract tests:
    .parse()
    and
    .safeParse()
    against schemas.
  • describe
    /
    it
    blocks,
    expect()
    matchers.
  • 测试环境设置为
    environment: 'node'
    ,测试用例存放于
    frontend/tests/*.test.ts
  • 契约测试调用schema的
    .parse()
    .safeParse()
    方法进行校验。
  • 使用
    describe
    /
    it
    块组织测试用例,使用
    expect()
    匹配器断言。

Commands

常用命令

Backend

后端

bash
cd backend && python -m pytest tests/ -v              # all tests
cd backend && python -m pytest tests/ -v -k <name>    # specific test
cd backend && ruff check --fix . && ruff format .     # lint+fix
cd backend && ruff check . && ruff format --check .   # lint check only
bash
cd backend && python -m pytest tests/ -v              # 运行所有测试
cd backend && python -m pytest tests/ -v -k <name>    # 运行指定测试
cd backend && ruff check --fix . && ruff format .     # 执行lint并自动修复+格式化
cd backend && ruff check . && ruff format --check .   # 仅执行lint和格式检查

Frontend

前端

bash
cd frontend && pnpm test          # all tests
cd frontend && pnpm test:watch    # watch mode
cd frontend && pnpm lint          # lint
cd frontend && pnpm format        # format
bash
cd frontend && pnpm test          # 运行所有测试
cd frontend && pnpm test:watch    # 启动监听模式运行测试
cd frontend && pnpm lint          # 执行lint检查
cd frontend && pnpm format        # 执行代码格式化