swagger-api / swagger-ui

Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.
https://swagger.io
Apache License 2.0
26.38k stars 8.92k forks source link

Correct way to post JSON list #220

Closed serpulga closed 11 years ago

serpulga commented 11 years ago

Hi, I'm trying to use SwaggerUI to perform a POST request to a flask application. I'm setting application/json as Content-Type header implicitly, but the flask application is not being able to parse the data into JSON. More specifically I'm trying to post lists. What would be the correct way to fill the fields in this case?

fehguy commented 11 years ago

Hi, can you give an example of the message being posted? We have a number of folks using swagger-ui + flask and lists are certainly supported.

serpulga commented 11 years ago

Yeah I thought so. What syntax should I follow to fill up the LIST type field?

simply: ["a", "b", "c"] ?

fehguy commented 11 years ago

Yes, that's right. There is a known "challenge" with flask though--I recall that the server barfs if you send Content-Type headers for a POST. Is that the case for you? I think the UI might be sending it all the time.

serpulga commented 11 years ago

I do send Content-Type: application/json. If I don't, flask won't parse it to JSON, and I would end up with unicode strings, like: '["a", "b", "c"]' type Unicode; ideally I would like to get ["a", "b", "c"] type list, in Python, which I do if I use CURL.

serpulga commented 11 years ago

I think the UI is always sending the data form-encoded, and application/json might need to be handled a bit differently.

serpulga commented 11 years ago

I performed the request using two different clients, and checked the request data using Chrome's web inspector:

Using Advanced Rest Client for Chrome, Content-Type : application/json Request Payload : {"teacher_id": "51af86eec9a50051bbe4dfb7"} Response : 200 OK

Using Swagger UI forms: Content-Type : application/json Request Payload : ------WebKitFormBoundary0OrjVsbKc6bZwesn Content-Disposition: form-data; name="teacher_id" 51af86eec9a50051bbe4dfb7 Response : 400

Advanced Rest Client lets me put in the RAW data, so I post a JSON object then the Flask app reads the Content-Type : application/json header and parses the data correctly, however, when it reads the application/json from Swagger UI and tries to parse the data as JSON, it fails.

fehguy commented 11 years ago

OK, from your second item, swagger-ui really thinks that you're trying to post FORM data, not json. I think you'll have to post your api declaration json to sort this out, because the UI is getting a hint that it's form data.

serpulga commented 11 years ago

Ok. How do I hint Swagger UI to post as JSON?

fehguy commented 11 years ago

Take a look here:

http://petstore.swagger.wordnik.com/#!/user/createUsersWithListInput_post_2

This accepts JSON in list format and the server parses it correctly. But I have a feeling that you're creating field names and expecting swagger to turn that into JSON, which it currently does not support. The user has to enter JSON, which can be facilitated by clicking the model schema in the right side.

Is that the case? You've defined a field and are looking for swagger to serialize the form fields into JSON and post it?

serpulga commented 11 years ago

Is that the case? You've defined a field and are looking for swagger to serialize the form fields into JSON and post >it?

Correct

serpulga commented 11 years ago

I get it know. I need to define my model and put that as the one parameter; what I was doing was adding every attribute as a separate form parameter and somehow expecting that to be posted as JSON. Thanks for your help.

fehguy commented 11 years ago

OK. I do think that we can get this into the UI though, automatically serializing a form into JSON. I'll keep you posted on that front

serpulga commented 11 years ago

yeah, it might be useful to some people. Maybe I could help out if pointed in the right direction.

fehguy commented 11 years ago

The right way to support this looks something like this:

1) the operation consumes application/json 2) the parameters have paramType=form

once this state is detected, the swagger-ui should serialize the input elements from the HTML form into JSON. It should actually be pretty easy, but that's how I'd tackle this. It is also strictly in the swagger-ui.js as opposed to the client library.

galoo commented 10 years ago

Hi, I have the same issue, I can't try my post using swagger, it's a bit disappointing :s Have you had the chance to develop this functionality? Thanks

serpulga commented 10 years ago

@galoo Yes. Simply posting the list as a JSON string: '["a", "b", "c"]' worked for me in the end.

fehguy commented 10 years ago

thanks @serpulga. Yes @galoo, the request was to automatically create a form for posting data instead of putting JSON in the text area. Posting lists of JSON works just fine.

galoo commented 10 years ago

Thank you for your feedback. Actually I'm in the case where I've got a list of parameters whose type is form. But when I'm sending the request, they're not automatically transformed into json. My server expects raw post data, not form data.

In the swagger doc generated, I can't specify the full json, I've got to enter a value for each parameter. Maybe the problem comes from the plugin I'm using to generate the swagger docs. It's django-rest-swagger. It's working well otherwise, but I'm a bit confused on how to test this post.

serpulga commented 10 years ago

I was also expecting the form parameters to be automatically converted to a JSON string, but that doesn't happen. When you have from parameters, Swag will post form-urlencoded data. In order to post a JSON object, you will need to type in the whole JSON array yourself into a Swager UI text area.

galoo commented 10 years ago

OK, thank you. Then I'll see how to display this text area.

fehguy commented 10 years ago

ok so in swagger FORM means just that--application/x-www-form-urlencoded. Not a form in the sense of UI.

If you want to generate an actual form is something you'll need to hack in. An example of one that somebody did recently is here:

http://lbovet.github.io/swagger-ui/dist/index.html

or here:

https://api.groupdocs.com/v2.0/spec/

galoo commented 10 years ago

Thank you, yes that's exactly what I would like to get actually.