skip to content

In Django REST Framework, how does the browsable API differ from generated OpenAPI documentation, and why is it no substitute?

level: juniorimportance: should knowfreq 44%

answer

  1. a renderer, not a document
  2. picked by the Accept header
  3. one endpoint, live, as you
  4. machine-readable contract for tools

basics

~20 s

The browsable API is an HTML renderer that shows one endpoint at a time, live, to a person in a browser acting as the current user. Generated OpenAPI documentation is a machine-readable description of every operation that partners and tools can use without your server.

solid answer

~40 s

The browsable API is `BrowsableAPIRenderer`, one of DRF's default renderers: when a browser's `Accept` header prefers `text/html`, the same view returns an HTML page with the response and forms for writable methods, built live and filtered by the current user's permissions. Generated documentation starts from an OpenAPI document that a schema generator builds from all views' serializers, parsers and renderers — DRF's own generator is deprecated in 3.18, so teams use a third-party one such as drf-spectacular. Only the document is a contract: it covers the whole API, needs no running server or account, can be versioned and reviewed, and drives client generators. So the browsable API is a development convenience; consumers get the schema.

code

python · 6 lines
python
# settings.py: JSON-only responses in production; schema docs are unaffected
REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": [
        "rest_framework.renderers.JSONRenderer",
    ],
}

go deeper

for a junior

Recall that the browsable API is an HTML renderer chosen by the browser's Accept header, while OpenAPI docs come from a generated document.

for a middle

Explain how content negotiation selects the renderer, why the browsable page is per endpoint and per user, and what a generator reads to build a schema.

for a senior

Say which one consumers get and why: the versioned OpenAPI document, with the browsable API often switched off in production by trimming the renderer list.

for a principal

Decide what the team's API contract is and where it lives, so the browsable API stays a development aid rather than an informal specification.

## Two things that both look like "API docs" A new DRF developer usually meets the **browsable API** first: open an endpoint URL in a browser and, instead of raw JSON, you get an HTML page with the response, the allowed methods, and forms for `POST`, `PUT` and `PATCH`. It is easy to conclude that the API documents itself. It does — for a human with a browser and an account — but it is a different thing from **generated OpenAPI documentation**, and interviewers ask the question to see whether you know where each one stops. ## How the browsable API works - It is a **renderer**, `BrowsableAPIRenderer`, listed in DRF's default `DEFAULT_RENDERER_CLASSES` next to `JSONRenderer`. Its media type is `text/html` and its format name is `api`. - **Content negotiation** picks it per request: a browser's `Accept` header prefers `text/html`, so the browser gets the HTML page, while a client asking for JSON gets JSON from the same view. `?format=json` in the URL forces the JSON output in a browser. - The page is built **live from the running view**: the response data, the view's docstring as the description, and one form per writable method, built by asking the view for a serializer once per form. - It runs **as the current user**. Permissions still apply, so an anonymous visitor sees only what an anonymous client could do. Session login for it is added by including `rest_framework.urls` under the `rest_framework` namespace. - It shows **one endpoint at a time**, following links; there is no single page listing every operation with its schemas. ## How generated OpenAPI documentation works - A **schema generator** walks the URLconf, finds DRF views, asks each view's schema inspector to describe its operations from serializers, parsers, renderers, pagination and filters, and compiles one **OpenAPI document** — a machine-readable description of every path, method, parameter, request body and response. - In DRF 3.18 the built-in generator (`SchemaGenerator` and `AutoSchema`) is **deprecated**; the DRF documentation recommends the third-party **drf-spectacular** package for OpenAPI 3. - A UI such as Swagger UI or Redoc renders that document as browsable reference pages; the document itself can also be committed, diffed and fed to client code generators. ## A side effect worth knowing To draw its forms, the browsable API asks the view for a serializer **once per form**, with the request method overridden to the form's method. During a plain `GET`, a view can therefore be called with `self.request.method` set to `POST`, `PUT`, `PATCH`, `DELETE` or `OPTIONS`, and permission classes are checked for each method before its form is rendered. A `get_serializer_class()` that branches on the method will see those values; DRF documents this as expected behaviour that only affects rendering the HTML page. ## Side by side | Question | Browsable API | Generated OpenAPI docs | |---|---|---| | Who reads it | A developer with a browser | People and tools | | Source | The live view, per request | A document generated from all views | | Scope | One endpoint at a time | The whole API in one file | | Needs a running server to read it | Yes | No, once generated | | Machine-readable contract | No | Yes | | Usable for client code generation | No | Yes | | Can be versioned and reviewed in a pull request | No | Yes, when committed as a file | ## Where each one earns its place 1. **During development**, the browsable API is the fastest way to poke an endpoint, submit a form and see validation errors without writing a client. 2. **For consumers** — a frontend team, a mobile team, an external partner — the contract has to be the OpenAPI document, because only it describes every operation without access to your server and can drive tooling. 3. **In production**, many teams remove `BrowsableAPIRenderer` from `DEFAULT_RENDERER_CLASSES`, so the API returns JSON only. That does not affect generated schema documentation, which is produced by a separate generator and served by its own view or file. ## Common misconceptions - The browsable API is not generated from the OpenAPI schema, and the schema is not generated from the browsable pages; both read the same views independently. - The `OPTIONS` metadata DRF returns (from `SimpleMetadata` by default) describes a single endpoint in DRF's own ad-hoc format; it is not OpenAPI. - DRF's built-in generator deliberately leaves the browsable renderer out of each operation's response media types, since HTML pages are not part of the API contract.

  • Why does the same URL return HTML in a browser and JSON to a script?
    DRF's content negotiation compares the request's `Accept` header with the view's renderer classes. A browser asks for `text/html` first, which matches `BrowsableAPIRenderer`; a script asking for `application/json`, or sending no preference, gets `JSONRenderer`. Adding `?format=json` to the URL overrides the header and shows the raw JSON in a browser.
  • Is the OPTIONS response a lightweight replacement for a schema?
    No. DRF answers `OPTIONS` through its metadata class, `SimpleMetadata` by default, which describes one endpoint's name, parsers, renderers and writable fields in DRF's own format. It is not OpenAPI, covers only the endpoint you asked, and no standard tooling consumes it.

saying these in an interview costs you the question

  • Believing the browsable API is rendered from the project's OpenAPI schema
  • Treating the browsable API as the contract handed to external consumers
  • Thinking removing BrowsableAPIRenderer also removes generated schema docs
  • Calling DRF's OPTIONS metadata response an OpenAPI description
  • Assuming the browsable API bypasses the view's permission checks