Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For GET request, parsed parameters from request_body are presented as response body #16

Closed
mkurnikov opened this issue Dec 15, 2017 · 3 comments
Assignees

Comments

@mkurnikov
Copy link

View code

from drf_yasg.utils import swagger_auto_schema
from rest_framework import serializers
from rest_framework.views import APIView


class IndexViewSerializer(serializers.Serializer):
    username = serializers.CharField()


class IndexView(APIView):
    @swagger_auto_schema(request_body=IndexViewSerializer)
    def get(self, request):
        pass

swagger spec generated

{
    "swagger":"2.0",
    "info":{
        "title":"Snippets API",
        "version":"v1"
    },
    "host":"localhost:8000",
    "schemes":[
        "http"
    ],
    "basePath":"/",
    "paths":{
        "/index/":{
            "get":{
                "operationId":"index_list",
                "description":"",
                "parameters":[

                ],
                "responses":{
                    "200":{
                        "description":"",
                        "schema":{
                            "type":"array",
                            "items":{
                                "$ref":"#/definitions/IndexView"
                            }
                        }
                    }
                },
                "consumes":[
                    "application/json"
                ],
                "tags":[
                    "index"
                ]
            },
            "parameters":[

            ]
        }
    },
    "definitions":{
        "IndexView":{
            "required":[
                "username"
            ],
            "type":"object",
            "properties":{
                "username":{
                    "type":"string"
                }
            }
        }
    },
    "securityDefinitions":{
        "basic":{
            "type":"basic"
        }
    }
}

As a workaround, I assume, one should specify parameters as openapi.Parameter objects, like

username_param = openapi.Parameter('username', in_=openapi.IN_QUERY, description='Username',
                                   type=openapi.TYPE_STRING)


class IndexView(APIView):
    @swagger_auto_schema(manual_parameters=[username_param])
    def get(self, request):
        pass

which works just fine.

@axnsan12
Copy link
Owner

axnsan12 commented Dec 15, 2017

The problem is in fact that, in django rest framework, there is no way for a view to declare what it returns, so this library assumes that endpoints which receive a request body return it back (for example, ModelViewSet which has a serializer_class which serializes both requests and responses)

For custom views like yours, the right thing is to also explicitly declare your response body in swagger_auto_schema, like for example responses: {200: ''} if it does not match the request body (see documentation here for details on how you can give details about response structure)

On the other hand, HTTP get requests are not usually expected to receive request bodies, that is generally only the case for POST, PUT, PATCH requests.

In your case, where what you really want is a query parameter, the manual_parameters way you gave in your last example is actually the correct way to add it. Giving a serializer to request_body would cause body parameters to be generated, not query parameters, which for GET does not really make sense.

--
Perhaps the conclusion to take from this issue is that a query_serializer option in swagger_auto_schema for generation of query parameters would be a useful addition.

A warning when passing request_body to unappropriate HTTP methods could also be useful.

@axnsan12 axnsan12 self-assigned this Dec 15, 2017
@mkurnikov mkurnikov reopened this Dec 15, 2017
@mkurnikov
Copy link
Author

Sorry.

Yes, I think query_serializer option would be the best one, as most of HTTP methods could have both query params and body.

axnsan12 added a commit that referenced this issue Dec 16, 2017
Allows for easier generation of query Parameters from a Serializer object.

See also #16.
@axnsan12
Copy link
Owner

Added & uploaded new version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants