How to display complex objects in multipart/form-data requests in Swagger UI? - multipartform-data

I am using OpenAPI 3.0.1 and I am trying to send a request as multipart/form-data. The request body is defined as follows:
requestBody:
content:
multipart/form-data: # Media type
schema: # Request payload
type: object
properties: # Request parts
media: # Part 1 (string value)
type: string
address: # Part2 (object)
type: object
properties:
street:
type: string
city:
type: string
profileImage: # Part 3 (an image)
type: string
format: binary
Here, the address field is an object. Swagger UI shows the address field itself, but does not show its properties street, city. Why is that?

This issue was fixed in Swagger UI v. 3.51.0. Make sure you're using the latest version.

Related

File schema object properties in openAPI

How do i define an openAPI schema for a file? I understand that it is an object but I don't know how to define it so that the person reading the document will understand that the given request contains file in a given key.
This is my current progress but I think it is completely wrong.
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
Could someone make a schema for me?
PS: I am using v3.1.0 of openAPI
Thanks!!

How do I interpret this OpenAPI array definition with the "properties" keyword?

Conside this OpenAPI schema:
Units:
type: array
properties:
empty:
type: boolean
items:
$ref: '#/components/schemas/Unit'
Swagger Editor renders it as follows:
How should I interpret the 'empty' property ? Why is it seen as an ordered map?
Normally an array has items but no direct properties in it.
In this schema, the properties section is effectively ignored. The properties section has effect only for type: object and in typeless schemas, but it's not used with arrays. So this definition is equivalent to:
Units:
type: array
items:
$ref: '#/components/schemas/Unit'
The "OrderedMap" text in Swagger Editor's model renderer can be considered a display bug. Feel free to open an issue for this here: https://github.com/swagger-api/swagger-ui/issues

Swagger 3.0 array's null values

Is it possible to define an array that can not contain null?
I'm compiling it to Java with Open API 3.0
For example for this
A:
type: array
minItems: 1
items:
$ref: "#/components/schemas/B"
B:
type: string
pattern: ^[a-z]+$
I consider [null] or ["abc",null] invalid
Thanks in advance

google cloud endpoints body array

We have a rest API that is written in Java (hosted in Wildfly). Our service is running in kubernetes (GKE). We want to leverage Cloud Endpoints to track usage and responsiveness of our API. The API is not new, we have been shipping software that interacts with it for years. It is also quite large (thousands of public methods). We have Swagger documentation for our API, and have no validation errors. When I try to deploy our Swagger using:
gcloud beta service-management deploy swagger.yaml
It is not successful. I get the following error repeated 237 times:
ERROR: unknown location: http: body field path 'body' must be a non-repeated message.
I have tracked it down to 237 methods that include a json array in a body parameter. In our API these are methods that either accept or return a list of objects.
Is there any way I can get this accepted by service-management deploy? Changing our API isn't an option, but we would really like to be able to use endpoints.
For example, this method signature:
#PUT
#Path ("/foobars/undelete")
#Consumes (MediaType.APPLICATION_JSON)
#Produces (MediaType.APPLICATION_JSON)
#ApiOperation (value = "Undelete foobars")
#ApiResponses (value =
{
#ApiResponse (
code = 200,
message = "foobars undeleted",
response = FooBar.class,
responseContainer = "List"
) , #ApiResponse (
code = 206,
message = "Not all foobars undeleted",
response = FooBar.class,
responseContainer = "List"
) , #ApiResponse (
code = 410,
message = "Not found"
) , #ApiResponse (
code = 500,
message = "Server Error"
)
})
public Response undeleteFooBars (#ApiParam (value = "FooBar ID List") List<UUID> entityIds)
generates this swagger snippet:
"/foobars/undelete":
put:
tags:
- foo
summary: Undelete FooBars
description: ''
operationId: undeleteFooBars
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: body
description: FooBar ID List
required: false
schema:
type: array
items:
type: string
format: uuid
responses:
'200':
description: Foo Bars undeleted
schema:
type: array
items:
"$ref": "#/definitions/FooBar"
'206':
description: Not all FooBars undeleted
schema:
type: array
items:
"$ref": "#/definitions/FooBar"
'410':
description: Not found
'500':
description: Server Error
I have had the exact same problem with Endpoints, where it does not seem to think that passing an array of objects is valid as a body parameter. I worked around this by just using a generic object and a decent description. The description will not programatically fix anything, but using a generic object allows Endpoints to work and the description gives information to the consumer of the API for what is expected.
parameters:
- in: body
name: body
description: Array of FooBar objects
required: false
schema:
type: object
This seems like an oversight on the part of the Endpoints team IMHO as using an array of objects in the body fits fine within the OpenApi spec and works with tools like http://editor.swagger.io/
Edit: I should also add that it is generally bad practice to use just a raw array as a request body or response body as it can cause a contract breaking change if additional properties are desired in the future, like say a count or pagination information.
If this is an existing API and you are just documenting the existing contract, then this solution will work to get the job done, but if you are designing a new API, then a better definition would be:
parameters:
- in: body
name: body
description: All the FooBar objects
required: false
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/definitions/FooBarResource'
Since this could later be extended to add additional properties like
parameters:
- in: body
name: body
description: All the FooBar objects
required: false
schema:
type: object
properties:
count:
type: integer
description: The total count of resources
callbackUrl:
type: string
description: The URL to trigger once creation is complete
items:
type: array
items:
$ref: '#/definitions/FooBarResource'
description: The resources to create
You can do better than a plain object. Yyou can specify an array as the the value of an object with a single key. This way you preserve your type information:
parameters:
- description: "Your items to add"
in: body
name: listings
required: true
schema:
type: object
properties:
payload:
type: array
maxItems: 1000
minItems: 1
$ref: "#/definitions/listing"
It's ugly but at least it documents whatever the model you are passing in should look like.

DRF/Angular: form data with nested objects with dotted/[] notation

I'm sending form data to Django Rest Framework View like this for all serialized data of a nested object named security:
------WebKitFormBoundaryAOygB8mq3Oo5I7ii
Content-Disposition: form-data; name="security[title]"
P
and it fails with 400 error saying that the field security is required.
When I'm using the DRF's web view and fill the form there, POST it I'm seeing that the notation is like this
------WebKitFormBoundaryAOygB8mq3Oo5I7ii
Content-Disposition: form-data; name="security.title"
P
As I'm using angular with ng-upload and its Upload lib (coffee):
Upload.upload(
url: '/services/rest/.../'+id+'/upload'
data:
$scope.object)
to send the form data.
Question which is correct? the dotted or [] notation? Which side to fix?
found it: Upload lib can be configured by objectKey: '.k'
details:
*data: {key: file, otherInfo: uploadInfo},
/*
This is to accommodate server implementations expecting nested data object keys in .key or [key] format.
Example: data: {rec: {name: 'N', pic: file}} sent as: rec[name] -> N, rec[pic] -> file
data: {rec: {name: 'N', pic: file}, objectKey: '.k'} sent as: rec.name -> N, rec.pic -> file */
objectKey: '[k]' or '.k' // default is '[k]'
You Should try make your key as security.title in FormData

Resources