How to describe a raw file body in RAML 1.0? - api

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

Related

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

Binary API documentation via swagger

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

ArrayIndexOutOfBoundsException use karate 0.8.0 [duplicate]

I'm trying to upload images on specific slack channel using Karate but no luck, I tried multiple times with different steps but still have 200 response and the image is not displayed in the channel.
Tried to post text content and successfully found the text on the channel.
Bellow are 2 of my tries following the Karate documentation:
#post
Feature: Post images
Background:
* url 'https://slack.com/api/files.upload'
* def req_params= {token: 'xxxxxxx',channels:'team',filename:'from Karate',pretty:'1'}
Scenario: upload image
Given path 'api','files'
And params req_headers
And multipart file myFile = { read: 'thumb.jpg', filename:
'upload-name.jpg', contentType: 'image/jpg' }
And multipart field message = 'image upload test'
And request req_headers
When method post
Then status 200
OR
Given path 'files','binary'
And param req_params
And request read('thumb.jpg')
When method post
Then status 200
Am I missing something? Tried the same examples found in Karate demo GitHub repository of uploading pdf and jpg but no luck.
Note: worked using Slack API UI.
You seem to be mixing up things, there is no need for a request body when you are using multipart. Your headers / params look off. Also based on the doc here, the name of the file-upload field is file. Try this:
Scenario: upload image
Given url 'https://slack.com/api/files.upload'
And multipart file file = { read: 'thumb.jpg', filename:
'upload-name.jpg', contentType: 'image/jpg' }
And multipart field token = 'xxxx-xxxxxxxxx-xxxx'
When method post
Then status 200
If this doesn't work, take the help of someone who can understand how to interpret the Slack API doc. Or get a Postman test working, then you'll easily figure out what you missed.

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'

Elixir: File upload to a REST API with json data

I'm trying to upload a file to a rest api using HTTPoison.
I can get a file upload to work with the following code, but I need to replace {"name", "value"} with a json payload or find a way to have json/nested data be sent with same request.
url = 'https://sandbox.e-signlive.com/api/packages/dc337476-9841-454a-b5d4-fe5a2b60136d/documents'
headers = [{"Authorization", "secret_key"}]
HTTPoison.post!("httpbin.org/post", {:multipart, [{"name", "value"}, {:file, "/Path/to/document.pdf"}]}, headers)
It seems enctype is missing:
enctype="multipart/form-data"