I'm building an API that's able to upload multiple files at once. I need to document it through swagger, but I have no experience with it at all.
My schema for the API is as follows:
The http request body is an octet-stream that looks like this. The first 4 bytes represents the number of packages, let the number of packages be n. The next 4*n bytes represents the sizes of the packages, where the first 4 bytes is the size of the first package, the next 4 is the size of the second package, etc. The end of the request simply consists of the packages.
An example would be: The packages \xDE\xAD\xBE\xEF and \xFE\xED\xFA\xCE\xCA\xFE\xBE\xEF, would compose the request:
\x00\x00\x00\x02||\x00\x00\x00\x04\x00\x00\x00\x08||\xDE\xAD\xBE\xEF\xFE\xED\xFA\xCE\xCA\xFE\xBE\xEF
I've tried documenting this in swagger like this:
Batch:
type: object
properties:
header:
description: The number of packages represented in binary (big endian).
type: string
format: binary
maxLength: 8
minLength: 8
example: \x00\x00\x00\x02
subheader:
description: The size of each package, where the size of the first package is represented by the first 4 bytes, the second by the next 4 bytes, etc (big endnian).
type: string
format: binary
maxLength: 4294967295
minLength: 0
example: \x00\x00\x00\x04\x00\x00\x00\x04
data:
description: The data block for encryption/decryption
type: string
format: binary
maxLength: 18446744073709551616
minLength: 0
example: \xDE\xAD\xBE\xEF\xDE\xAD\xBE\xEF
But it shows the request body as a json object (due to type: object).
Any ideas on how to do this properly?
Octet-stream request body is defined as a single binary string. There's no way to define the contents/format of specific fragments of the octet-stream. minLength and maxLength can be used to limit the size of the entire stream.
Also note that this is OpenAPI 3.0. OpenAPI 2.0 does not support application/octet-stream payloads (it only supports multipart/form-data).
openapi: 3.0.2
paths:
/something:
post:
requestBody:
required: true
content:
application/octet-stream:
schema:
type: string
format: binary
maxLength: 12345
Related
I am currently using IBM API Connect as my application for creating my API. I have an input parameter that I would like to set the maxLength for, and have it so the API is throwing an error if the input for the parameter is larger than the maxLength defined. Currently I have the code below, and the API is still allowing for much larger strings than 10. I was just curious is I for one am defining the maxLength for the input parameter correctly, and two, if the IBM API Connect framework just doesn't provide the ability to set a max length for an input parameter.
parameters:
- name: test2
type: string
maxLength: 10
minimum: 1
maximum: 10
required: false
in: query
description: test2
having issues with reading data from multipart/form-data after the request goes through ApiKit router in Mule4 app.
There is a RAML in place, used in ApiKit router to validate & route the requests.
#%RAML 1.0
title: ACC race data API
description: API for designing and updating race data
version: 1
protocols: [ HTTPS, HTTP ]
/acc/reverse/entrylist:
description: Used to manipulate entrylist for ACC reverse grid.
post:
description: Creates new entrylist based on supplied quali result, race one result and race one entrylist.
queryParameters:
positionsRotated:
description: Parameter defining how many positions to rotate.
required: false
type: number
example: 30
body:
multipart/form-data:
properties:
qualifyResult:
description: File containing qualifying result.
type: file
fileTypes: ['application/json']
required: true
raceOneResult:
description: File containing race 1 result.
type: file
fileTypes: ['application/json']
required: true
The validation works fine - if the data are sent in incorrect format, the exception is returned. For correctly formated data request is routed to the flow post:\acc\reverse\entrylist:multipart\form-data:acc-race-data-config.
Between the steps, payload format is changed (by Mule) from payload in readable form (see below) to java.io.ByteArrayInputStream#379ebdd5
Readable format of payload data (received to the app) before ApiKit router:
----------------------------180928595588258919887097
Content-Disposition: form-data; name="qualifyResult"; filename="json1.json"
Content-Type: application/json
{
"json1": "1"
}
----------------------------180928595588258919887097
Content-Disposition: form-data; name="raceOneResult"; filename="json2.json"
Content-Type: application/json
{
"json2": "2"
}
----------------------------180928595588258919887097--
The following dataweave script works fine if used before apiKit, but it doesn't work in the flow called by ApiKit:
%dw 2.0
output application/json
---
payload.parts[1].content
The example of output if above DW is used before ApiKit:
{
"json2": "2"
}
The example of output if the same DW is used after ApiKit:
org.mule.runtime.core.api.expression.ExpressionRuntimeException: "javax.mail.internet.ParseException - Missing start boundary, while reading `payload` as MultiPart.
Trace:
at main (Unknown)" evaluating expression: "%dw 2.0
output application/json
---
payload.parts[1].content".
Testing in Anypoint Studio 7.8.0, supposed to be used on Mule4-CE runtime once finished and ready to deploy.
Using Postman v8.5.1 for testing. sending form-data body with qualifyResult and raceOneResult parts containing JSON data, default headers, basic auth, query param positionsRotated=30.
Url called: https://localhost:443/api/acc/reverse/entrylist?positionsRotated=30
Tried to generate multipart/form-data body manually using a RAW type of payload, but the results were the same. Everything works fine if there is no ApiKit.. but I would like to use it to validate request validity.
Thanks to everyone replying for any useful hints!
I tested a similar scenario I had with the latest versions and I didn't had that problem. If you are using older versions of the HTTP connector and APIKit module try upgrading to the latest releases. Anypoint Studio has a feature to detect newer releases of connectors: https://docs.mulesoft.com/studio/7.9/update-modules
I have below requirement for designing simple RAML. I’m newbie in RAML coding so would like to know if my code is according to requirement or not
Requirement:
Has at least 1 endpoint with a GET and POST method.
Includes description attribute of the API
Includes description attribute of the method
The GET request takes a query parameter of "mulesoft"
Define the response with an object that contains least a string and
integer data type
Includes an example for a 200 response code that matches the
definition’s response object from above
My code:
#%RAML 1.0
title: Coding_Champions
version: 1.0.development
baseUri: http://localhost:8004/api
description: This API displays and adds Organisation with details
types:
Org:
type: object
properties:
name: string
address: string
pincode: integer
/details:
displayName: Company Details
description: Coding challenge which takes query parameter of "mulesoft"
get:
description: Retrieve a list of all the Orgs
queryParameters:
mulesoft:
description: Specify the Org name that you want to retrieve
type: boolean
required: true
responses:
200:
body:
application/json:
type: Org
examples:
MuleSoft:
name: MuleSoft
address: 77 Geary Street, Suite 400
pincode: 94108
post:
description: Add a Org to list
body:
application/json:
type: Org
examples:
Cognizant:
name: Cognizant
address: DLF
pincode: 9771
responses:
201:
body:
application/json:
example: |
{
"message":"New Org updated but not really"
}
I’m more of concerned with one of point in the requirement
"The GET request takes a query parameter of “mulesoft”
Does it mean I should give mulesoft as parameter dynamically in my url, If yes then other than mulesoft is passed as parameter then it should throw an error ?
(or)
Does it mean i need to hard code “mulesoft” in my RAML code as I have done now ?
Can you please clear me on this ?
Does it mean I need to hard code “mulesoft” in my RAML code as I have
done now ?
Yes.You should define that in RAML as you are doing right now.Since its required parameter,its presence could be validated in implementation.
I am trying to call a POST method which accepts the below form parameters
Path – A string specifying the path
FileName - A binary file
Media Type: multipart/form-data
Below code helps with the binary file part
Given multipart file xxx= { read: 'classpath:xxx', filename: 'xxx'}
However, in the same request I need to pass the string parameter as well.
Please suggest a way.
Thanks,
Kanika
You can combine multipart field with multipart file, refer to this demo example also.
Given multipart file xxx = { read: 'classpath:xxx', filename: 'xxx' }
And multipart field yyy = 'myvalue'
I have an API endpoint which allows user to upload a file and a request payload is a raw file contents. How can I describe this in a RAML documentation?
I use suck structure, but it doesn't seem correct to me
post:
description: Use this endpoint to upload a new image.
headers:
X-File-Name: Image file name.
body:
file:
description: Send raw file contents in a request payload
Thanks.
In RAML 1 you can use the file type:
types:
customFile:
type: file
fileTypes: ['*/*'] # any file type allowed
maxLength: 1048576
And then use it like this:
/someresource:
post:
body:
application/octet-stream:
type: customFile