2

Using orjson to serializing response has a remarkable effect on the speed of fastAPI restful services, specifically for very big objects. As I have read in the official documentation, we can use the response class directly as a parameter of api method. The problem is that when I use the ORJSONResponse directly as a function it works; however, it doesn't work when passing it into parameter esponse_class=ORJSONResponse.

1. sample code with direct calling of ORJSONResponse():

this code run in 75ms ,size 6.6 MB that shows orjson serialization works properly. It's faster than .net core and it is what I need.

from fastapi import APIRouter

from fastapi.responses import ORJSONResponse

router=APIRouter()
__all__=["router"]

siz=1000000
ret=[None]*siz
for i in range(0,siz-1):
    ret[i]=i

@router.get("/planlist"))
def plan_list():
    ORJSONResponse(ret)
   

2. sample code with passing ORJSONResponse as parameter:

this code runs just like without response class set. it takes 876 ms more than 10 times longer in the same 6.6MB size. it shows orjson has not been set correctly.

from fastapi import APIRouter
from fastapi.responses import ORJSONResponse

router=APIRouter()
__all__=["router"]

siz=1000000
ret=[None]*siz
for i in range(0,siz-1):
    ret[i]=i

@router.get("/planlist",response_class=ORJSONResponse)
def plan_list():

    for i in range(0,siz-1):
        ret[i]=i

    return ret

Test platform

  • Test client: ansomnia core 2020.4.1, same results in postman 7.34.0
  • Os: MacOS catalina 10.15.7, same results for windows 10
  • cpu: core i9
1
  • Future readers might find this answer helpful as well. Commented Jan 17, 2024 at 6:49

2 Answers 2

4

Also, we have documentation for Returning a Response Directly.

So you can use this, not a bad practice.

return ORJSONResponse(content=data)

But this will skip the validation, serialization and automatic documentation, which will give you huge flexibility and performance but which also means, you need to make sure the contents are ready for it and you need to manually design OpenAPI schemas.

Sign up to request clarification or add additional context in comments.

3 Comments

Maybe the for loop in the second example causes this huge difference. Otherwise, this is so strange.
Thanks for answering, yes in this particular case, because of large data size time is important rather than validation. so validation is mostly need in input here it is out put.
and about for statement, I have set it out side of the method in module global scope and when it is called data is data is ready. it cant cause big time deference .
1

You can now use orjson as a default response class/type as mentioned in the docs

A small example

from fastapi import FastAPI
from fastapi.responses import ORJSONResponse

app = FastAPI(default_response_class=ORJSONResponse)


@app.get("/items/")
async def read_items():
    return [{"item_id": "Foo"}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.