connexion icon indicating copy to clipboard operation
connexion copied to clipboard

Use orjson instead of json for JSON serialization

Open advance512 opened this issue 5 years ago • 4 comments

Description

The authors of orjson describe it like this:

orjson is a fast, correct JSON library for Python. It benchmarks as the fastest Python library for JSON and is more correct than the standard json library or other third-party libraries.

Based on the benchmarks the authors have shared, orjson is 5 to 50 times faster than the standard json library.

Expected behaviour

Add an option to use orjson instead of json.

Actual behaviour

json is the only option for JSON serialization.

advance512 avatar May 13 '20 17:05 advance512

Comparing the standard Jsonifier used by Connexion and orjson in an example API call in my application, I see the difference in performance can be extreme, 570 times faster:

FlaskApi._serialize_data():

# 2434078 bytes, total time 8ms
body = orjson.dumps(data, option=orjson.OPT_NAIVE_UTC | orjson.OPT_NON_STR_KEYS)

# 3899087 bytes, total time 4565ms
body = cls.jsonifier.dumps(data)

To validate the output, I used json.loads() and verified that it creates identical objects. It does.

advance512 avatar May 13 '20 18:05 advance512

Please also include the option to use orjson for deserialisation.

backbord avatar Nov 08 '21 06:11 backbord

Isn't this possible by custom json encoder? In connexion 2.x

connexion_app.app.json_encoder = CustomJSONEncoder

and by jsonifier in connexion=3.x

jsonifier=Jsonifier(kw.json)

lucas03 avatar Jan 30 '24 14:01 lucas03

Jsonifier unfortunately always adds JSONEncoder to dumps calls: self.dumps_args.setdefault("cls", JSONEncoder) which is not allowed for orjson.

You can work around this by subclassing Jsonifier:

import orjson

class OrJsonifier(Jsonifier):
    """A Jsonifier that uses orjson for serialization and deserialization."""

    def dumps(self, data, **_kwargs):
        return orjson.dumps(data).decode()

connexion_app = AsyncApp(name, jsonifier=OrJsonifier())

Note that the original Jsonifier adds an (unnecessary) trailing newline.

houbie avatar Feb 23 '24 13:02 houbie