Reputation: 53843
I'm building a simply API using Django Rest Framework. This API does not store anything, but functions as a proxy to another API to query whether a store has milk. So I made a simple serializer and view:
class HasMilkSerializer(serializers.Serializer):
store = serializers.CharField(min_length=6, max_length=6)
passage_at = serializers.DateTimeField()
class HasMilkView(CsrfExemptMixin, APIView):
http_method_names = ['post']
authentication_classes = [BasicAuthWithKeys]
serializer_classes = [HasMilkSerializer]
def post(self, request):
store = request.data['store']
visit_at = parser.parse(request.data['visit_at'])
return Response({'store': store, 'has_milk': has_milk(store, visit_at)})
This works great, so now I want to document this in OpenAPI specs using drf-yasg. I've installed it and swagger shows some info, but it doesn't show any specs on parameters or responses (see screenshot below).
What do I need to do to get swagger to properly document my endpoint? Do I need to define it further in swagger, or do I need to change the endpoint so that swagger can properly document it?
Upvotes: 0
Views: 3105
Reputation: 66
A couple of things first:
APIView
(or the other classes that inherit from it), the attribute to define the serializer class to be used is serializer_class
, not serializer_classes
.As far the question goes, since you are using the APIView
class, drf-yasg
cannot infer the request & response body using a model queryset. Thus, you have to manually add the response and request body using the swagger_auto_schema
decorator. You could do something like this:
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
class HasMilkView(CsrfExemptMixin, APIView):
http_method_names = ['post']
authentication_classes = [BasicAuthWithKeys]
serializer_classes = [HasMilkSerializer]
@swagger_auto_schema(
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
required=['store', 'visit_at'],
properties={
'store': openapi.Schema(type=openapi.TYPE_STRING,
max_length=6),
'visit_at': openapi.Schema(type=openapi.TYPE_STRING,
format=FORMAT_DATE)
}
),
responses={
200: openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
'store': openapi.Schema(type=openapi.TYPE_STRING,
max_length=255),
'has_milk': openapi.Schema(type=openapi.TYPE_BOOLEAN)
}
)
}
)
def post(self, request):
store = request.data['store']
visit_at = parser.parse(request.data['visit_at'])
return Response({'store': store, 'has_milk': has_milk(store, visit_at)})
Upvotes: 2
Reputation: 221
APIView does not have the serializer_classes attribute and swagger can not detect your serializer automatically. you can use another type of View like GenericAPIView or ModelViewSet.
or
if you want use APIView, you should use @swagger_auto_schema decorator for defining your request/response parameters:
@swagger_auto_schema(request_body=HasMilkSerializer)
def post(self, request):
store = request.data['store']
visit_at = parser.parse(request.data['visit_at'])
return Response({'store': store, 'has_milk': has_milk(store, visit_at)})
Upvotes: 3