Skip to content

Commit

Permalink
docs(media): add an example for using a custom JSON encoder (#2035)
Browse files Browse the repository at this point in the history
* Add an example for using a custom json encoder with media handlers.

* reword the doc to read better.

* Return the default.

* Cross-link from FAQ page for easier discovery.

* Fix another typo.

* Fix a typo and use rubric for hyperlinks.

* docs(media): tweak JSONHandler's rubrics

Co-authored-by: Vytautas Liuolia <vytautas.liuolia@gmail.com>
  • Loading branch information
maxking and vytas7 committed Mar 8, 2022
1 parent 43a8e80 commit 89a615a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/user/faq.rst
Expand Up @@ -915,6 +915,10 @@ Furthermore, different Internet media types such as YAML,
types than JSON, either as part of the respective (de)serialization format, or
via custom type extensions.

.. seealso:: See :ref:`custom-media-json-encoder` for an example on how to
use a custom json encoder.


Does Falcon set Content-Length or do I need to do that explicitly?
------------------------------------------------------------------
Falcon will try to do this for you, based on the value of
Expand Down
40 changes: 40 additions & 0 deletions falcon/media/json.py
Expand Up @@ -26,6 +26,8 @@ class JSONHandler(BaseHandler):
library's JSON implementation, since it will be faster in most cases
as compared to a third-party library.
.. rubric:: Custom JSON library
You can replace the default JSON handler by using a custom JSON library
(see also: :ref:`custom_media_handlers`). Overriding the default JSON
implementation is simply a matter of specifying the desired ``dumps`` and
Expand All @@ -48,6 +50,8 @@ class JSONHandler(BaseHandler):
app.req_options.media_handlers.update(extra_handlers)
app.resp_options.media_handlers.update(extra_handlers)
.. rubric:: Custom serialization parameters
Even if you decide to stick with the stdlib's :any:`json.dumps` and
:any:`json.loads`, you can wrap them using :any:`functools.partial` to
provide custom serialization or deserialization parameters supported by the
Expand Down Expand Up @@ -94,6 +98,42 @@ class JSONHandler(BaseHandler):
),
)
.. _custom-media-json-encoder:
.. rubric:: Custom JSON encoder
You can also override the default :class:`~json.JSONEncoder` by using a
custom Encoder and updating the media handlers for ``application/json``
type to use that::
import json
from datetime import datetime
from functools import partial
import falcon
from falcon import media
class DatetimeEncoder(json.JSONEncoder):
\"\"\"Json Encoder that supports datetime objects.\"\"\"
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
app = falcon.App()
json_handler = media.JSONHandler(
dumps=partial(json.dumps, cls=DatetimeEncoder),
)
extra_handlers = {
'application/json': json_handler,
}
app.req_options.media_handlers.update(extra_handlers)
app.resp_options.media_handlers.update(extra_handlers)
Keyword Arguments:
dumps (func): Function to use when serializing JSON responses.
loads (func): Function to use when deserializing JSON requests.
Expand Down

0 comments on commit 89a615a

Please sign in to comment.