Binary API documentation via swagger - api

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

Defining Max Length in IBM API Connect

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

Multipart/form-data broken after apiKit router Mule4

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

RAML Code understanding

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.

How to pass string and file as input for form parameters in a POST method using Karate

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'

How to describe a raw file body in RAML 1.0?

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