elya5
elya5

Reputation: 2258

Define component schema with drf-spectacular for django API

I am using drf-spectacular to generate an OpenAPI schema for django. As I am not using serializers, I am defining everything in the extend_schema decorator. Now my question is, if it is possible to manually define a component schema.

Here is an example what my api view looks like:

from rest_framework.decorators import api_view
from drf_spectacular.utils import (extend_schema, OpenApiExample)
from drf_spectacular.types import OpenApiTypes
from rest_framework.response import Response

@extend_schema(
    examples=[OpenApiExample(
        value=[
            {'title': 'A title'},
            {'title': 'Another title'},
        ],
    )],
    responses={
       200: OpenApiTypes.OBJECT
    }
)
@api_view(['GET'])
def list_articles(request):
    return Response([{'title': 'Test1'}, {'title': 'Test2'}])

and the corresponding component is shown as empty (e.g. in swagger):

swagger-ui example of empty component

Here is the definition in the documentation but I cannot figure out how to achieve it with drf-spectacular.

Upvotes: 3

Views: 10366

Answers (2)

rzlvmp
rzlvmp

Reputation: 9442

Also it is possible to use simple dictionary instead of inline_serializer:

@extend_schema(
    ...
    responses={
        (200, 'text/html'): {
            'description': 'Simple HTML page',
            'type': 'string',
            'example': '<html>Example text</html>'
        },
        (202, 'application/json'): {
            'description': 'JSON response',
            'type': 'object',
            'properties': {
                'title': {
                    'type': 'string',
                    'minLength': 1,
                    'maxLength': 128
                }
            },
            'required': [
                'title'
            ]
        },
    }
)
...

Upvotes: 1

Insa
Insa

Reputation: 1881

OpenApiTypes.OBJECT means that the response object can have any amount of fields. Of course Swagger UI cannot know those fields in advance and thus it shows {}, which may be unintuitive but it is correct.

What you want is to give your response some structure. Everything in spectacular revolves around serializers/components. If you don't want to have explicit serializers, you can create implicit ones with inline_serializer

from drf_spectacular.utils import extend_schema, OpenApiExample, inline_serializer

@extend_schema(
    examples=[OpenApiExample(
        value=[
            {'title': 'A title'},
            {'title': 'Another title'},
        ],
    )],
    responses={
       200: inline_serializer(
           name='Article',
           fields={
               'title': serializers.CharField(),
           }
       )
    }
)
@api_view(['GET'])
def list_articles(request):
    pass

Upvotes: 11

Related Questions