diff --git a/docs/en/docs/advanced/custom-response.md b/docs/en/docs/advanced/custom-response.md
index 8b4b3da33..e88e95865 100644
--- a/docs/en/docs/advanced/custom-response.md
+++ b/docs/en/docs/advanced/custom-response.md
@@ -1,6 +1,6 @@
# Custom Response - HTML, Stream, File, others { #custom-response-html-stream-file-others }
-By default, **FastAPI** will return the responses using `JSONResponse`.
+By default, **FastAPI** will return JSON responses.
You can override it by returning a `Response` directly as seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}.
@@ -10,43 +10,27 @@ But you can also declare the `Response` that you want to be used (e.g. any `Resp
The contents that you return from your *path operation function* will be put inside of that `Response`.
-And if that `Response` has a JSON media type (`application/json`), like is the case with the `JSONResponse` and `UJSONResponse`, the data you return will be automatically converted (and filtered) with any Pydantic `response_model` that you declared in the *path operation decorator*.
-
/// note
If you use a response class with no media type, FastAPI will expect your response to have no content, so it will not document the response format in its generated OpenAPI docs.
///
-## Use `ORJSONResponse` { #use-orjsonresponse }
-
-For example, if you are squeezing performance, you can install and use `orjson` and set the response to be `ORJSONResponse`.
-
-Import the `Response` class (sub-class) you want to use and declare it in the *path operation decorator*.
+## JSON Responses { #json-responses }
-For large responses, returning a `Response` directly is much faster than returning a dictionary.
+By default FastAPI returns JSON responses.
-This is because by default, FastAPI will inspect every item inside and make sure it is serializable as JSON, using the same [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} explained in the tutorial. This is what allows you to return **arbitrary objects**, for example database models.
+If you declare a [Response Model](../tutorial/response-model.md){.internal-link target=_blank} FastAPI will use it to serialize the data to JSON, using Pydantic.
-But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class.
-
-{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
-
-/// info
-
-The parameter `response_class` will also be used to define the "media type" of the response.
-
-In this case, the HTTP header `Content-Type` will be set to `application/json`.
-
-And it will be documented as such in OpenAPI.
+If you don't declare a response model, FastAPI will use the `jsonable_encoder` explained in [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} and put it in a `JSONResponse`.
-///
+If you declare a `response_class` with a JSON media type (`application/json`), like is the case with the `JSONResponse`, the data you return will be automatically converted (and filtered) with any Pydantic `response_model` that you declared in the *path operation decorator*. But the data won't be serialized to JSON bytes with Pydantic, instead it will be converted with the `jsonable_encoder` and then passed to the `JSONResponse` class, which will serialize it to bytes using the standard JSON library in Python.
-/// tip
+### JSON Performance { #json-performance }
-The `ORJSONResponse` is only available in FastAPI, not in Starlette.
+In short, if you want the maximum performance, use a [Response Model](../tutorial/response-model.md){.internal-link target=_blank} and don't declare a `response_class` in the *path operation decorator*.
-///
+{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
## HTML Response { #html-response }
@@ -154,40 +138,6 @@ Takes some data and returns an `application/json` encoded response.
This is the default response used in **FastAPI**, as you read above.
-### `ORJSONResponse` { #orjsonresponse }
-
-A fast alternative JSON response using `orjson`, as you read above.
-
-/// info
-
-This requires installing `orjson` for example with `pip install orjson`.
-
-///
-
-### `UJSONResponse` { #ujsonresponse }
-
-An alternative JSON response using `ujson`.
-
-/// info
-
-This requires installing `ujson` for example with `pip install ujson`.
-
-///
-
-/// warning
-
-`ujson` is less careful than Python's built-in implementation in how it handles some edge-cases.
-
-///
-
-{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
-
-/// tip
-
-It's possible that `ORJSONResponse` might be a faster alternative.
-
-///
-
### `RedirectResponse` { #redirectresponse }
Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.
@@ -268,7 +218,7 @@ In this case, you can return the file path directly from your *path operation* f
You can create your own custom response class, inheriting from `Response` and using it.
-For example, let's say that you want to use `orjson`, but with some custom settings not used in the included `ORJSONResponse` class.
+For example, let's say that you want to use `orjson` with some settings.
Let's say you want it to return indented and formatted JSON, so you want to use the orjson option `orjson.OPT_INDENT_2`.
@@ -292,13 +242,21 @@ Now instead of returning:
Of course, you will probably find much better ways to take advantage of this than formatting JSON. 😉
+### `orjson` or Response Model { #orjson-or-response-model }
+
+If what you are looking for is performance, you are probably better off using a [Response Model](../tutorial/response-model.md){.internal-link target=_blank} than an `orjson` response.
+
+With a response model, FastAPI will use Pydantic to serialize the data to JSON, without using intermediate steps, like converting it with `jsonable_encoder`, which would happen in any other case.
+
+And under the hood, Pydantic uses the same underlying Rust mechanisms as `orjson` to serialize to JSON, so you will already get the best performance with a response model.
+
## Default response class { #default-response-class }
When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default.
The parameter that defines this is `default_response_class`.
-In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`.
+In the example below, **FastAPI** will use `HTMLResponse` by default, in all *path operations*, instead of JSON.
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
diff --git a/docs/en/docs/advanced/response-directly.md b/docs/en/docs/advanced/response-directly.md
index 76cc50d03..9d58490eb 100644
--- a/docs/en/docs/advanced/response-directly.md
+++ b/docs/en/docs/advanced/response-directly.md
@@ -2,19 +2,23 @@
When you create a **FastAPI** *path operation* you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc.
-By default, **FastAPI** would automatically convert that return value to JSON using the `jsonable_encoder` explained in [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+If you declare a [Response Model](../tutorial/response-model.md){.internal-link target=_blank} FastAPI will use it to serialize the data to JSON, using Pydantic.
-Then, behind the scenes, it would put that JSON-compatible data (e.g. a `dict`) inside of a `JSONResponse` that would be used to send the response to the client.
+If you don't declare a response model, FastAPI will use the `jsonable_encoder` explained in [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} and put it in a `JSONResponse`.
-But you can return a `JSONResponse` directly from your *path operations*.
+You could also create a `JSONResponse` directly and return it.
-It might be useful, for example, to return custom headers or cookies.
+/// tip
+
+You will normally have much better performance using a [Response Model](../tutorial/response-model.md){.internal-link target=_blank} than returning a `JSONResponse` directly, as that way it serializes the data using Pydantic, in Rust.
+
+///
## Return a `Response` { #return-a-response }
-In fact, you can return any `Response` or any sub-class of it.
+You can return any `Response` or any sub-class of it.
-/// tip
+/// info
`JSONResponse` itself is a sub-class of `Response`.
@@ -56,6 +60,18 @@ You could put your XML content in a string, put that in a `Response`, and return
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
+## How a Response Model Works { #how-a-response-model-works }
+
+When you declare a [Response Model](../tutorial/response-model.md){.internal-link target=_blank} in a path operation, **FastAPI** will use it to serialize the data to JSON, using Pydantic.
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+As that will happen on the Rust side, the performance will be much better than if it was done with regular Python and the `JSONResponse` class.
+
+When using a response model FastAPI won't use the `jsonable_encoder` to convert the data (which would be slower) nor the `JSONResponse` class.
+
+Instead it takes the JSON bytes generated with Pydantic using the response model and returns a `Response` with the right media type for JSON directly (`application/json`).
+
## Notes { #notes }
When you return a `Response` directly its data is not validated, converted (serialized), or documented automatically.
diff --git a/docs/en/docs/tutorial/response-model.md b/docs/en/docs/tutorial/response-model.md
index 51492722a..c8312d92c 100644
--- a/docs/en/docs/tutorial/response-model.md
+++ b/docs/en/docs/tutorial/response-model.md
@@ -13,6 +13,7 @@ FastAPI will use this return type to:
* Add a **JSON Schema** for the response, in the OpenAPI *path operation*.
* This will be used by the **automatic docs**.
* It will also be used by automatic client code generation tools.
+* **Serialize** the returned data to JSON using Pydantic, which is written in **Rust**, so it will be **much faster**.
But most importantly: