Files
connexion/docs/response.rst
2023-10-16 23:51:21 +02:00

186 lines
6.4 KiB
ReStructuredText

Response Handling
=================
When your application returns a response, Connexion provides the following functionality based on
your OpenAPI spec:
- It automatically translates Python errors into HTTP problem responses (see :doc:`exceptions`)
- It automatically serializes the response for certain content types
- It validates the response body and headers (see :doc:`validation`)
On this page, we zoom in on the response serialization.
Response Serialization
----------------------
.. tab-set::
.. tab-item:: AsyncApp
:sync: AsyncApp
When working with Connexion, you can return ordinary Python types, and connexion will serialize
them into a network response.
.. tab-item:: FlaskApp
:sync: FlaskApp
When working with Connexion, you can return ordinary Python types, and connexion will serialize
them into a network response.
.. tab-item:: ConnexionMiddleware
:sync: ConnexionMiddleware
When working with Connexion, you can return ordinary Python types, and connexion will serialize
them into a network response.
To activate this behavior when using the ``ConnexionMiddleware`` wrapping a third party
application, you can leverage the following decorators provided by Connexion:
* ``FlaskDecorator``: provides automatic parameter injection and response serialization for
Flask applications.
.. code-block:: python
:caption: **app.py**
from connexion import ConnexionMiddleware
from connexion.decorators import FlaskDecorator
from flask import Flask
app = Flask(__name__)
app = ConnexionMiddleware(app)
app.add_api("openapi.yaml")
@app.route("/endpoint")
@FlaskDecorator()
def endpoint(name):
...
* ``StarletteDecorator``: provides automatic parameter injection and response serialization
for Starlette applications.
.. code-block:: python
:caption: **app.py**
from connexion import ConnexionMiddleware
from connexion.decorators import StarletteDecorator
from starlette.applications import Starlette
from starlette.routing import Route
@StarletteDecorator()
def endpoint(name):
...
app = Starlette(routes=[Route('/endpoint', endpoint)])
app = ConnexionMiddleware(app)
app.add_api("openapi.yaml")
For a full example, see our `Frameworks`_ example.
The generic ``connexion.decorators.WSGIDecorator`` and
``connexion.decorators.ASGIDecorator`` unfortunately don't support response
serialization, but you can extend them to implement your own decorator for a specific
WSGI or ASGI framework respectively.
.. note::
If you implement a custom decorator, and think it would be valuable for other users, we
would appreciate it as a contribution.
.. code-block:: python
:caption: **api.py**
def endpoint():
data = "success"
status_code = 200
headers = {"Content-Type": "text/plain}
return data, status_code, headers
Data
````
If your API returns responses with the ``application/json`` content type, you can return
a simple ``dict`` or ``list`` and Connexion will serialize (``json.dumps``) the data for you.
**Customizing JSON serialization**
Connexion allows you to customize the ``Jsonifier`` used to serialize json data by subclassing the
``connexion.jsonifier.Jsonifier`` class and passing it when instantiating your app or registering
an API:
.. tab-set::
.. tab-item:: AsyncApp
:sync: AsyncApp
.. code-block:: python
:caption: **app.py**
from connexion import AsyncApp
app = AsyncApp(__name__, jsonifier=)
app.add_api("openapi.yaml", jsonifier=c)
.. tab-item:: FlaskApp
:sync: FlaskApp
.. code-block:: python
:caption: **app.py**
from connexion import FlaskApp
app = FlaskApp(__name__, jsonifier=...)
app.add_api("openapi.yaml", jsonifier=...):
.. tab-item:: ConnexionMiddleware
:sync: ConnexionMiddleware
.. code-block:: python
:caption: **app.py**
from asgi_framework import App
from connexion import ConnexionMiddleware
app = App(__name__)
app = ConnexionMiddleware(app, jsonifier=...)
app.add_api("openapi.yaml", jsonifier=...)
Status code
```````````
If no status code is provided, Connexion will automatically set it as ``200`` if data is
returned, or as ``204`` if ``None`` or ``connexion.datastructures.NoContent`` is returned.
Headers
```````
The headers can be used to define any response headers to return. If your OpenAPI specification
defines multiple responses with different content types, you can explicitly set the
``Content-Type`` header to tell Connexion which response to validate against.
If you do not explicitly return a ``Content-Type`` header, Connexion's behavior depends on the
Responses defined in your OpenAPI spec:
* If you have defined a single response content type in your OpenAPI specification, Connexion
will automatically set it.
* If you have defined multiple response content types in your OpenAPI specification, Connexion
will try to infer which one matches your response and set it. If it cannot infer the content
type, an error is raised.
* If you have not defined a response content type in your OpenAPI specification, Connexion will
automatically set it to ``application/json`` unless you don't return any data. This is mostly
because of backward-compatibility, and can be circumvented easily by defining a response
content type in your OpenAPI specification.
Skipping response serialization
-------------------------------
If your endpoint returns an instance of ``connexion.lifecycle.ConnexionResponse``, or a
framework-specific response (``flask.Response`` or ``starlette.responses.Response``), response
serialization is skipped, and the response is passed directly to the underlying framework.
If your endpoint returns a `Response`
If the endpoint returns a `Response` object this response will be used as is.
.. _Frameworks: https://github.com/spec-first/connexion/tree/main/examples/frameworks