I'm experiencing some issues when using file properties nested within a requestBody. I'm new to this library, so feel free to point out if I'm just neglecting to consider something basic or obvious -- it's entirely possible this is my own openapi-fu lacking here.
Using:
Ruby: 3.4.1
Rails: 8.0.1
Rspec: 3.13, Rspec Rails: 7.1.1
openapi_first: 2.2.3
OpenAPI 3.0
Use Case 1: No Nesting
openapi.yaml
openapi: 3.0.3
# ...
paths:
'/api/v1/signup':
$ref: 'paths/signup.yaml'
paths/signup.yaml
patch:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
# ...
avatar:
type: string
format: binary
responses:
# ...
Spec:
it 'should PATCH with avatar file' do
body = {
avatar: fixture_file_upload('image.jpg')
}
patch user_registration_path,
params: body,
headers: {
'Content-Type': 'multipart/form-data'
}
end
No middleware error, works fine.
Use Case 2: Nested file property
paths/signup.yaml
patch:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
user:
type: object
properties:
# ...
avatar:
type: string
format: binary
responses:
# ...
Spec:
it 'should PATCH with avatar file' do
body = {
user: {
avatar: fixture_file_upload('image.jpg')
}
}
patch user_registration_path,
params: body,
headers: {
'Content-Type': 'multipart/form-data'
}
end
Results in error response:
{
errors: [
{
code: "string",
source: {
pointer: "/user/avatar"
},
status: "400",
title: "value at `/user/avatar` is not a string"
},
{
code: "format",
source: {
pointer: "/user/avatar"
},
status: "400",
title: "value at `/user/avatar` does not match format: binary"
}
]
}
Use Case 3: Array of Files
paths/signup.yaml
patch:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
# ...
filesArray:
type: array
items:
type: string
format: binary
responses:
# ...
Spec:
it 'should PATCH with avatar file' do
body = {
filesArray: [
fixture_file_upload('image.jpg')
]
}
patch user_registration_path,
params: body,
headers: {
'Content-Type': 'multipart/form-data'
}
end
Results in error:
{
errors: [
{
code: "string",
source: {
pointer: "/filesArray/0"
},
status: "400",
title: "value at `/filesArray/0` is not a string"
},
{
code: "format",
source: {
pointer: "/filesArray/0"
},
status: "400",
title: "value at `/filesArray/0` does not match format: binary"
}
]
}
Use Case Four, Array of Objects with with file property
paths/signup.yaml
patch:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
# ...
filesObjArray:
type: array
items:
type: object
properties:
file:
type: string
format: binary
responses:
# ...
Spec:
it 'should PATCH with avatar file' do
body = {
filesObjArray: [
{ avatar: fixture_file_upload('image.jpg') }
]
}
patch user_registration_path,
params: body,
headers: {
'Content-Type': 'multipart/form-data'
}
end
Results in error response:
{
errors: [
{
code: "string",
source: {
pointer: "/filesObjArray/0/file"
},
status: "400",
title: "value at `/filesObjArray/0/file` is not a string"
},
{
code: "format",
source: {
pointer: "/filesObjArray/0/file"
},
status: "400",
title: "value at `/filesObjArray/0/file` does not match format: binary"
}
]
}
OpenAPI 3.1
If I keep using format: binary, I'll get mostly the same errors, minus the does not match format: binary error, which makes some sense.
If I replace the use of format: binary with something like contentMediaType: application/octet-stream or image/jpeg, I get a different thrown error:
JSONSchemer::UnknownContentMediaType:
application/octet-stream
I can also use the empty {} for typing to avoid the errors, but this seems incorrect since it's tacitly an unknown/any type.
Considerations
In all of the above, if I remove the OpenapiFirst::Middlewares::RequestValidation middleware and the underlying controller code supports the body structure, actual functionality works fine in spec, postman, javascript client, etc
I'm experiencing some issues when using file properties nested within a requestBody. I'm new to this library, so feel free to point out if I'm just neglecting to consider something basic or obvious -- it's entirely possible this is my own openapi-fu lacking here.
Using:
Ruby: 3.4.1
Rails: 8.0.1
Rspec: 3.13, Rspec Rails: 7.1.1
openapi_first: 2.2.3OpenAPI 3.0
Use Case 1: No Nesting
openapi.yamlpaths/signup.yamlSpec:
No middleware error, works fine.
Use Case 2: Nested file property
paths/signup.yamlSpec:
Results in error response:
Use Case 3: Array of Files
paths/signup.yamlSpec:
Results in error:
Use Case Four, Array of Objects with with file property
paths/signup.yamlSpec:
Results in error response:
OpenAPI 3.1
If I keep using
format: binary, I'll get mostly the same errors, minus thedoes not match format: binaryerror, which makes some sense.If I replace the use of
format: binarywith something likecontentMediaType: application/octet-streamorimage/jpeg, I get a different thrown error:I can also use the empty
{}for typing to avoid the errors, but this seems incorrect since it's tacitly an unknown/any type.Considerations
In all of the above, if I remove the
OpenapiFirst::Middlewares::RequestValidationmiddleware and the underlying controller code supports the body structure, actual functionality works fine in spec, postman, javascript client, etc