mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-06 04:19:26 +00:00
186 lines
6.4 KiB
ReStructuredText
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
|