docs: rewrite Web APIs category intro

The intro predated the 2026-10-02 audit and did not mention the newly added flask-restx and flask-smorest.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Vinta Chen
2026-10-02 16:17:16 +08:00
co-authored by Claude
parent 288048afb5
commit 77b29c0d28
+19 -21
View File
@@ -1,33 +1,31 @@
Outside Django, declare each FastAPI endpoint with type hints. Django projects add a Python API framework on top instead: Django REST framework or Django Ninja.
Type hints alone let FastAPI validate requests and document your API. Python API frameworks for Django include Django Ninja, which reads them too.
How to choose:
- Django, with CRUD endpoints over your models: Django REST framework
- Django, with endpoints declared by type hints: Django Ninja
- A new service outside Django: FastAPI
- GraphQL over Django models: Strawberry GraphQL Django
- Django, with msgspec, attrs, or dataclass schemas: django-modern-rest
- A Flask app: APIFlask
- A new API, not tied to Django or Flask: FastAPI
- Typed endpoints in a Django project: Django Ninja
- CRUD endpoints over Django models, with a browsable API: Django REST framework
- GraphQL types generated from Django models: Strawberry Django
- msgspec, attrs, or dataclass schemas on Django: django-modern-rest
- Flask resources grouped into namespaces, with Swagger docs: Flask-RESTX
- marshmallow schemas on Flask blueprints: flask-smorest
- A Flask app validated with Pydantic models or marshmallow: APIFlask
- GraphQL on FastAPI or any other framework: Strawberry
- An OpenAPI spec written before the code: Connexion
- GraphQL on FastAPI, Flask, or another framework: Strawberry
- RPC between services in any language: gRPC
- Calls between services written in different languages: gRPC
Django REST framework adds serializers and a [browsable API](https://www.django-rest-framework.org/) to Django. For CRUD over your models, [group the views in a `ModelViewSet` and register it with a router](https://www.django-rest-framework.org/tutorial/quickstart/). For an OpenAPI schema, its docs [recommend drf-spectacular](https://www.django-rest-framework.org/topics/documenting-your-api/#drf-spectacular). By default, the API [allows unrestricted access](https://www.django-rest-framework.org/api-guide/permissions/#setting-the-permission-policy), so set a policy in `DEFAULT_PERMISSION_CLASSES`.
FastAPI is [based on standard Python type hints](https://fastapi.tiangolo.com/). Declare path, query, and body parameters as typed function arguments, and it validates them and serves interactive docs at `/docs`. As the app grows, split it into modules with [`APIRouter`, a "mini FastAPI"](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
Django Ninja is [heavily inspired by FastAPI](https://django-ninja.dev/motivation/) and works with Django's ORM, URLs, views, and auth. You write each endpoint as a function with type hints, and it [generates the OpenAPI docs](https://django-ninja.dev/) from them. Run async views on [an ASGI server](https://django-ninja.dev/guides/async-support/). If you use Django's cookie-based auth, [keep Django's CSRF protection on](https://django-ninja.dev/reference/csrf/#use-djangos-built-in-csrf-protection).
Django Ninja was [heavily inspired by FastAPI](https://django-ninja.dev/) and integrates with Django's core and ORM. You declare parameter and body types once, as function arguments, and the interactive docs show up at `/api/docs`. For a bigger project, [create an `api.py` with a `Router` in each Django app](https://django-ninja.dev/guides/routers/).
FastAPI builds [request validation and OpenAPI docs from standard type hints](https://fastapi.tiangolo.com/), on top of Pydantic and Starlette. Install `fastapi[standard]`, which brings Uvicorn and the `fastapi` command: run `fastapi dev` while you work and [`fastapi run` in production](https://fastapi.tiangolo.com/fastapi-cli/).
Django REST framework [splits an API into](https://www.django-rest-framework.org/) serializers for the representation, viewsets for the behavior, and routers for the URLs. [Viewsets get you running quickly](https://www.django-rest-framework.org/api-guide/viewsets/) and keep URLs consistent across a large API, while plain views are more explicit. For OpenAPI schemas, its docs [recommend drf-spectacular](https://www.django-rest-framework.org/topics/documenting-your-api/).
Strawberry GraphQL Django [builds types from your Django models](https://strawberry.rocks/docs/django), while Strawberry alone [only provides a GraphQL view](https://strawberry.rocks/docs/integrations/django) for Django. Add its [query optimizer](https://strawberry.rocks/docs/django/guide/optimizer), which calls `select_related()` and `prefetch_related()` for you to avoid N+1 queries.
APIFlask has you [use `APIFlask` instead of `Flask`](https://apiflask.com/), then declare request and response schemas with [`@app.input` and `@app.output`](https://apiflask.com/usage/). flask-smorest [organizes resources as `MethodView` classes in blueprints](https://flask-smorest.readthedocs.io/en/latest/quickstart.html), with marshmallow schemas on `Blueprint.arguments` and `Blueprint.response`. Flask-RESTX [splits your app into reusable namespaces](https://flask-restx.readthedocs.io/en/latest/scaling.html), much like blueprints, and describes them for Swagger through decorators.
django-modern-rest [drops into an existing Django app](https://django-modern-rest.readthedocs.io/en/latest/) and validates both requests and responses against your schemas: msgspec, Pydantic, attrs, dataclasses, and more. Its docs [recommend always installing msgspec](https://django-modern-rest.readthedocs.io/en/latest/pages/getting-started.html#installation) to parse JSON, even when your schemas are Pydantic models.
Strawberry [builds on dataclasses and type hints](https://strawberry.rocks/docs), and FastAPI's docs [recommend it for GraphQL](https://fastapi.tiangolo.com/how-to/graphql/). Before going to production, [disable GraphiQL and introspection](https://strawberry.rocks/docs/operations/deployment), and turn on Strawberry's security extensions that limit query depth, aliases, and tokens.
APIFlask is a [thin wrapper on Flask](https://apiflask.com/migrations/flask/): swap `Flask` for `APIFlask` and `Blueprint` for `APIBlueprint`, and your [Flask extensions keep working](https://apiflask.com/comparison/#apiflask-vs-fastapi). Declare each endpoint's input and output with `@app.input()` and `@app.output()`, as [marshmallow schemas or Pydantic models](https://apiflask.com/), and APIFlask generates the OpenAPI docs from them.
Strawberry Django [creates GraphQL types from your Django models](https://strawberry.rocks/docs/django). Add its [`DjangoOptimizerExtension`](https://strawberry.rocks/docs/django/guide/optimizer), which calls `select_related()` and `prefetch_related()` for you to avoid N+1 queries.
Connexion is spec-first: you write the OpenAPI spec, and Connexion [routes and validates requests against it](https://connexion.readthedocs.io/en/latest/#why-connexion), so server and client can be built in parallel. FastAPI goes the other way, and its maintainer says it's [not meant for writing the schema first](https://github.com/fastapi/fastapi/discussions/6169). Start a new project on [`AsyncApp`](https://connexion.readthedocs.io/en/latest/quickstart.html#creating-your-application), or on `FlaskApp` to keep the Flask ecosystem.
Connexion flips the usual order: you [write the OpenAPI spec first](https://connexion.readthedocs.io/en/latest/), then the code, and Connexion validates requests against the spec. Each `operationId` in the spec [names the Python function that handles it](https://connexion.readthedocs.io/en/latest/routing.html). Start new projects on [`AsyncApp`, or on `FlaskApp` to use the Flask ecosystem](https://connexion.readthedocs.io/en/latest/quickstart.html).
Strawberry builds a GraphQL schema from [dataclasses and type hints](https://strawberry.rocks/docs), and FastAPI's docs [recommend it for GraphQL](https://fastapi.tiangolo.com/how-to/graphql/#graphql-with-strawberry). Before you deploy, [turn off GraphiQL and introspection](https://strawberry.rocks/docs/operations/deployment), and add the [security extensions](https://strawberry.rocks/docs/operations/deployment#security-extensions) that limit query depth, aliases, and tokens.
gRPC has you [define a service once in a `.proto` file](https://grpc.io/docs/languages/python/basics/) and generate its clients and servers in any language gRPC supports. Install `grpcio` and `grpcio-tools`, and [compile the `.proto` file into Python code with `grpc_tools.protoc`](https://grpc.io/docs/languages/python/quickstart/). [Use TLS](https://grpc.io/docs/guides/auth/) to authenticate the server and encrypt the traffic.
Keep separate models for what an endpoint takes in and what it sends back. FastAPI [filters the response through the output model](https://fastapi.tiangolo.com/tutorial/response-model/#add-an-output-model), so fields the output model leaves out, like a password, never reach the client. APIFlask [recommends separate input and output schemas](https://apiflask.com/schema/#marshmallow) too.
gRPC lets you [define a service once in a `.proto` file](https://grpc.io/docs/languages/python/basics/) and generate clients and servers in any language it supports. For asyncio code, gRPC has [`grpc.aio`](https://grpc.github.io/grpc/python/grpc_asyncio.html).