Swagger2.0 is not enforcing type during GET request after posting json object array through formdata
See original GitHub issueQ&A
- OS: macOS
- Browser: CHROME
- Swagger/OpenAPI version: Swagger 2.0
Problem
The schema definition for string field(stringified json object array string) is only restricting the POST/PUT request. During processing GET request, the request is directly returning the data inside mongoDB in json object array format instead of String. Also, if is an empty array, the GET request won’t return such a field. I would like it to be in empty array format.
Content & configuration
Related issue: https://github.com/form-data/form-data/issues/92
I use Swagger2.0, mongoDB as database. I am trying to send a json object array to flask backend and store in MongoDB. Since formdata doesn’t allow objects. I come up with the following solution. Firstly, I did stringify() operation during sending formdata and decode in the Flask server side using json.loads(). Surprisingly, even though I defined the schema in the swagger UI for such field as string(I have to do so to make sure the data is not splited by mongoDB based on comma). During GET request, it will directly get the json array instead of string format expected in the swagger yaml… This indeed satisfies my need, but it doesn’t make sense. Swagger is not transforming the json object array in mongoDB to string type again, instead, it allows the GET request to directly return the structured json object array data. That’s good, but why, it is not restricting the type or throw any error.
Could someone give me an explanation on this? Thanks.
Definition
definitions:
OCRTruth:
type: "object"
required:
- "filename"
properties:
filename:
type: "string"
# The field causing problems
categorySpecificData:
type: "string"
API endpoint definition
During making POST/PUT request, the string field categorySpecifcData is retricted to be in string format. I did a manual decoding before storing into MongoDB. In GET request, the return categorySpecificData is not enforcing string type. It is directly a json object format in mongoDB, I understand I can do post-processing in controller here, but why the yaml is not reporting type error. Second problem, if it is a empty array, the field will be missing in the return json.
# GET request
/ocr_truth:
get:
tags:
- "OCR Truth"
summary: "Finds OCR Truth data"
description: "Return a list of truth data"
operationId: "app.api.ocrtruth_controller.class_instance.get"
produces:
- "application/json"
parameters:
- name: "filename"
in: "query"
description: "The filename of the OCR truth data to return"
required: false
type: "string"
default: null
x-nullable: true
- name: "filename_like"
in: "query"
description: "The filename of the OCR truth data to return"
required: false
type: "string"
default: null
x-nullable: true
responses:
200:
description: "successful operation"
schema:
type: "array"
items:
$ref: "#/definitions/OCRTruth"
400:
description: "Invalid filename"
# POST request
/ocr_truth/upload:
post:
tags:
- "OCR Truth"
summary: "Upload a new receipt"
description: ""
operationId: "app.api.ocrtruth_controller.class_instance.upload_receipt"
consumes:
- "multipart/form-data"
parameters:
- in: "formData"
name: "filename"
description: "The receipt to be uploaded"
type: "file"
required: true
- in: "formData"
name: "categorySpecificData"
description: "Category specific data of the receipt"
type: "string"
required: true
responses:
200:
description: "Ok"
# PUT request
/ocr_truth/updateByFilename:
put:
tags:
- "OCR Truth"
summary: "Update an existing truth data by filename"
description: ""
operationId: "app.api.ocrtruth_controller.class_instance.update_by_filename"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "truth_data_payload"
description: "Truth data that will replace the old data"
required: true
schema:
$ref: "#/definitions/OCRTruth"
responses:
400:
description: "Invalid ID supplied"
404:
description: "OCR Truth not found"
405:
description: "Validation exception"
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Flask is not one of our projects and we don’t know it so we can’t help your implementation questions, sorry. Try Flask support channels or general programming forums such as Stack Overflow.
Adding a field to the
required
is the OpenAPI way to tell that this field must be present in the payload - regardless of the value, i.e. even if the value is an empty array/empty string/null/etc. If this doesn’t happen, then it’s a bug in the code that generates responses. I.e. could be a Flask bug.I understand your point. I use Python Flask server with WSGI here. It will produce some kind of error based on yaml definition. Please refer to the screenshot below. In theory, I guess some similar error will be produced if the GET request is not returning the string format. However, it does not do that. Instead, it can fulfill the GET with json object array without problem and it can be parsed by the browser. Do you have any idea on such behavior? Thanks!
For the second question, the missing field for empty array. I agree with you, it should be an issue in server side… I just would like to know if there is anything I can do to check against such a field in swagger UI. Put it into the
required
part seems doesn’t help much. Any suggestion?