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

Can't send formData with GET requests. #198

Closed
rhythmize opened this issue May 4, 2018 · 14 comments
Closed

Can't send formData with GET requests. #198

rhythmize opened this issue May 4, 2018 · 14 comments
Assignees

Comments

@rhythmize
Copy link

rhythmize commented May 4, 2018

I'm trying to make a GET request to my api, using flasgger-ui. But I get the response:

{
  "status": "400 BAD REQUEST",
  "type": "error",
  "description": {
    "name": "Provide valid name."
  }
}

As the endpoint expects a parameter in formBody and data is not parsed properly by flasgger-ui, I get this response.
Another important point is the CURL request command generated at flasgger-ui , if run directly from terminal. Gives the expected results.
And I can even send data in formBody with GET request if I use python requests module.
I can't figure out whats wrong.

Please explain.

@rhythmize
Copy link
Author

Has anybody noticed this issue?

@rochacbruno
Copy link
Member

@Code-Player can you provide a simple app (in form of gist.github.com where I can reproduce the problem?

@rhythmize
Copy link
Author

https://gist.github.com/code-player/eea29e0be69bd7f0592b9c3e9e753538
@rochacbruno
Try running above code.
First use swagger-ui to make request and then use the CURL command provided in swagger-ui to make same request.
You will see the difference in response generated for each requests.

@rochacbruno
Copy link
Member

The error is explicit TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.

While curl allows us to send GET along with formData looks like swagger is more strict about it and does not allow sending it to conform with HTTP specs.

I am trying to find a way to configure swagger to be less strict and add it as an option to configure.

@rhythmize
Copy link
Author

I can send formData even with other modules like requests. And furthermore, we can have formBody with GET Request as well. Its just people usually send data in url itself, thats why its not very often. But I need to send have this feature in APIs because I have to send data in get request as well. No other request module prevent this feature.

I am trying to find a way to configure swagger to be less strict and add it as an option to configure.

That would be really helpful.
Thnaks

@javabrett
Copy link
Collaborator

javabrett commented Aug 8, 2018

Note that when moving from Swagger 2.0 to OpenAPI 3.0, the 3.0 specification has tightened-up on this and no-longer permits a GET (or any other operation which does not have defined semantics as per RFC 7231. It will reject validation with:

GET operations cannot have a requestBody.

https://swagger.io/docs/specification/describing-request-body/
https://swagger.io/specification/#operationRequestBody

The request body applicable for this operation. The requestBody is only supported in HTTP methods where the HTTP 1.1 specification RFC7231 has explicitly defined semantics for request bodies. In other cases where the HTTP spec is vague, requestBody SHALL be ignored by consumers.

That means, no more GET with body payloads - stick to one of the P's POST, PUT or PATCH.

Given OpenAPI 3.0 has deliberately tightened this up, I'd be hesitant to backport support for it for Swagger 2.0.

@javabrett javabrett self-assigned this Aug 8, 2018
@rhythmize
Copy link
Author

Okay, but even RFC 7231 says

A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.

So if I'm at the point of designing APIs and need to send some sensitive information to server inside body even for GET request, I am allowed to do that and even basic requesting libraries like CURL, requests(in python) and okhttp(in android) responds well.

@javabrett
Copy link
Collaborator

I totally agree that GET with a body is permitted in HTTP, just as a POST with a query(-string) (?foo=bar) is also permitted. My point above is that Swagger -> OpenAPI in their 3.0 spec has expressly forbid APIs with GET bodies. This is a change/clarification from 1.2/2.0. Do you read it the same?

Ergo if you write an API which reads from a GET body, it won't be OpenAPI 3.0 compliant. It can be anything else and completely valid HTTP and REST and what-not, but it won't comply with OpenAPI 3.0. Given that, I thought it might be hasty to backport it to flasgger even for Swagger 1.2/2.0. @rochacbruno may have opinions on this, and they may differ from mine.

You haven't detailed why you must use GET and not say POST or PUT. GET by-convention should be idempotent and without side-effects or state-changes, so sending data is not conventional. Can't use headers or query-string with TLS?

@rhythmize
Copy link
Author

Headers I'm using for Authentication. And I defer to use query-string because data could be logged by any logger which logs the application activity. Also have too much data in query-string also end up with url-too-long error.
And thanks for your replies and explaining your point.

@javabrett
Copy link
Collaborator

I noticed today that test/demo app http://javabrett.pythonanywhere.com/changelog_090/apidocs/ suffers from this issue, since its GET endpoint is declared to accept formData.

Per above, my inclination is to not support this. I suppose it boils down to whether flasgger should allow workarounds at the edges of the Swagger and OpenAPI specifications, or whether it should not attempt to support such things.

/cc @rochacbruno .

@rhythmize
Copy link
Author

Same was the case with me, I have also designed my APIs GET endpoints to accept formData and it was working fine with simple CURL requests or any http(s)-request module in other programming language.

@rochacbruno
Copy link
Member

@javabrett My opinion is that we should support strictly what OpenAPI and Swagger supports, if a workaround is needed then the user is able to do it by monkey patching, inheriting or forking.

@rhythmize
Copy link
Author

Yeah, sure.

@javabrett
Copy link
Collaborator

I'm closing this based on the above discussion and reasoning.

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

No branches or pull requests

3 participants