1

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 Answers1

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.

Yagiz Degirmenci
  • 16,595
  • 7
  • 65
  • 85
  • 1
    Maybe the for loop in the second example causes this huge difference. Otherwise, this is so strange. – Yagiz Degirmenci Oct 17 '20 at 23:51
  • 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. – Ahad Rafat Talebi Oct 18 '20 at 10:44
  • 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 . – Ahad Rafat Talebi Oct 18 '20 at 10:47