🗑️ Deprecate `ORJSONResponse` and `UJSONResponse` by tiangolo · Pull Request #14964 · fastapi/fastapi
🗑️ Deprecate ORJSONResponse and UJSONResponse
Now that there's better performance by default, with response models: #14962
This removes ujson and orjson from the "fastapi[all]" extras.
To use these responses, ujson or orjson need to be explicitly installed.
tiangolo
marked this pull request as ready for review
With this deprecation, what's the recommended approach for exception handlers that return plain dict bodies?
For example:
@app.exception_handler(ValidationError) async def validation_error_handler(request: Request, exception: ValidationError) -> Response: return ORJSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={"errors": exception.errors()}, )
Since exception handlers don't use Pydantic return types, they don't benefit from the Pydantic serialization. Should we just switch to JSONResponse and accept the performance difference, or is there another approach?
With this deprecation, what's the recommended approach for exception handlers that return plain dict bodies?
You can copy the implementation of ORJSONResponse and use it instead of importing from fastapi.
Or, you can return Response(content=ujson.dumps(content, ensure_ascii=False).encode("utf-8")).
Don't forget to add ujson explicit dependency to your project
Are there any benchmark or something?
@tmdgusya I ran benchmarks for my responses (#14299 (comment)). Feel free to plug in yours and check.
@YuriiMotov thanks for the answer! Though I think deprecating these classes is a mistake, for plain dict serialization, orjson are still significantly faster than stdlib, and that's free performance. Copying the implementation feels like a workaround for removing something that's still useful.
@YuriiMotov thanks for the answer! Though I think deprecating these classes is a mistake, for plain dict serialization, orjson are still significantly faster than stdlib, and that's free performance. Copying the implementation feels like a workaround for removing something that's still useful.
Do you mean routes like this:
@app.get("/default") def get_default() -> dict: return {"name": "widget", "price": 9.99}
?
In this case FastAPI will also serialize it with Pydantic, not stdlib:
Details
from unittest.mock import patch from fastapi import FastAPI from fastapi.testclient import TestClient from pydantic import BaseModel class Item(BaseModel): name: str price: float app = FastAPI() @app.get("/default") def get_default() -> dict: return {"name": "widget", "price": 9.99} client = TestClient(app) def test_default_response_class_skips_json_dumps(): """When no response_class is set, the fast path serializes directly to JSON bytes via Pydantic's dump_json and never calls json.dumps.""" with patch( "starlette.responses.json.dumps", wraps=__import__("json").dumps ) as mock_dumps: response = client.get("/default") assert response.status_code == 200 assert response.json() == {"name": "widget", "price": 9.99} mock_dumps.assert_not_called()
If you still think we need to de-deprecate these classes, please open a discussion and let's continue discussing it there
Oh my bad, I didn't realize Pydantic could serialize plain dicts too! In that case, should Pydantic serialization become the default for JSONResponse as well?
Edit: I just started a discussion on this topic #14980
I came across this PR and would like to ask whether fastapi plans to support additional third‑party JSON libraries. I have developed a new high‑performance JSON library, ssrJSON, whose overall performance surpasses orjson, particularly in handling non‑ASCII strings and floating‑point numbers. ssrJSON provides dumps and dumps_to_bytes, returning str and UTF‑8‑encoded bytes, respectively, and it might be useful for fastapi (I’m not very familiar with fastapi yet, sorry if I'm wrong).
If fastapi is still going to support third‑party JSON libraries, I can add features to ssrJSON to integrate with fastapi, for example ssrJSON currently does not serialize numpy types and also some of the types that orjson already supports. Are there specific types that fastapi requires a JSON encoder to support at minimum? Or should I open a new issue/discussion to discuss this further?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters