How to add a content-type on a POST request with no body in OpenAPI 3.0? - openapi

I am trying to create an OpenAPI 3.0 definition for an existing API. It has a POST operation and takes header values as the input. Request body is empty. However the backend API was coded very poorly and is expecting request header Content-Type: application/json even though the body is empty.
How do I achieve this in OpenAPI 3.0? Looks like Content-Type is not accepted as a valid header parameter in OAS 3.0.

You can add the requestBody with the application/json media type but no schema.
openapi: 3.0.2
...
paths:
/something:
post:
parameters:
...
requestBody:
content:
application/json: {}

with Insomnia when use:
requestBody:
content:
application/json: {}
result is this: (preview)
but if use this:
requestBody:
content:
application/json:
schema: # Request body contents
type: object
result is : (preview)

Based on Open API 3 spec, your requestBody should be like the following:
requestBody:
required: true
description: blabla.
content:
application/json:
schema:
type: object
nullable: true

Related

Openapi v3 dynamic Accept and Content-Type headers

For one particular endpoint in OpenAPI v3 spec, I need to manually handle request mime-type. It's a GET request, where the user should specify Accept header, and the service loads some data and encodes it into one of multiple supported formats to respond with. I'm trying to specify Accept and Content-Type in spec:
/example:
get:
description: Example endpoint
operationId: example
parameters:
- name: Accept
in: header
required: true
schema:
type: string
responses:
'200':
description: OK
content:
'*/*':
schema:
type: string
format: binary
headers:
Content-Type:
description: Content type
schema:
format: string
'404':
description: Not found
'406':
description: Unsupported mime-type
But codegen tool print warnings:
WARN Accept is described separately and will be ignored in this section {"at": "spec.yml:96:11"}
WARN Content-Type is described separately and will be ignored in this section {"at": "spec.yml:111:15"}
and doesn't generate these headers in code.
How should I pass these dynamic params to request and response?
I don't want to describe all supported mime-types in spec, because the list of supported formats may change dynamically without changing the code, and I don't want need to recompile the server every time I add or remove new mime-type encoder.

How to write a response for an MP3 file in OpenAPI YAML?

I am writing an API YAML that returns an MP3 file. I am not familiar with multimedia responses. While going through Google I found that I can use the audio/mp3 content type. But I couldn't find any example showing how to do it. How should I address this audio content type?
OpenAPI 3.1
A binary file response is defined with just the media type and no schema:
openapi: 3.1.0
...
paths:
/something:
get:
responses:
'200':
description: An audio file
content:
audio/mp3: {}
OpenAPI 3.0
Files are defined as binary strings (type: string + format: binary):
openapi: 3.0.3
...
paths:
/something:
get:
responses:
'200':
description: An audio file
content:
audio/mp3:
schema:
type: string
format: binary
OpenAPI 2.0
Binary file responses are defined with a type: file schema. Make sure to also specify the media type in the operation's produces list:
swagger: '2.0'
...
paths:
/something:
get:
produces:
- audio/mp3
responses:
200:
description: An audio file
schema:
type: file

Can't make DREDD to use the schema.example as POST body

I'm trying to use Dredd to test my OpenAPI specified API but I can't get Dredd to recognize the JSON body of my POST requests, it keeps sending my POST requests with an empty body.
According to Dredd's documentation it uses the schema.example for "in": "body" and that's exactly what I am doing but Dredd keeps issuing the POST with empty body.
I've tried both OpenAPI3 and OpenAPI2 with the same result. My POST operation in OpenAPI2 specification looks like this:
/availableCounters:
post:
summary: Get the available counters for a specified time range
description: This API returns the available counters for the specific time range requested.
responses:
'200':
description: OK
schema:
type: object
properties:
properties:
type: array
items:
$ref: '#/definitions/property_spec'
'400':
description: 'Could not retrieve available Counters: ${error}'
parameters:
- required: true
name: body
in: body
schema:
example: {"searchSpan": {"from": {"dateTime": "2019-01-20T21:50:37.349Z"},"to": {"dateTime": "2019-01-22T21:50:37.349Z"}}}
type: object
properties:
searchSpan:
$ref: '#/definitions/from_to'
But when I use Dredd to test this OpenAPI definition, for this operation it doesn't send the body as it should:
request:
method: POST
uri: /availableCounters
headers:
User-Agent: Dredd/8.0.0 (Windows_NT 10.0.17134; x64)
body:
expected:
headers:
statusCode: 200
bodySchema: {"type":"object","properties":{"properties":{"type":"array","items":{"$ref":"#/definitions/property_spec"}}},"definitions":{"property_spec":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["Double","String","DateTime"]}}}}}
actual:
statusCode: 400
headers:
connection: close
date: Tue, 12 Feb 2019 23:22:09 GMT
content-type: text/plain; charset=utf-8
server: Kestrel
content-length: 96
bodyEncoding: utf-8
body:
Could not retrieve available Counters: TypeError: Cannot read property 'searchSpan' of undefined
I've tried using both schema.example and schema.x-example but Dredd will not send the body. As I've said previously I've also tried OpenAPI3 and I get the same result.
Any help would be greatly appreciated.
The question is old, but the problem is still there: Dredd seems to ignore the body parameter, if the consumes field is missing.
So try:
/availableCounters:
post:
summary: Get the available counters for a specified time range
consumes:
- application/json
[...]

How to set the Accept header globally in OpenAPI 3.0?

I have a new OpenAPI setup via SwaggerHub. Is there an option to force a certain Accept header globally?
I have set up the Content-Type on the response:
openapi: 3.0.0
paths:
/test-path:
get:
responses:
'200':
description: OK
content:
application/vnd.company.v1.0.0+json:
When inserting a different Accept header via cURL request, the following out is made:
{"message":"Missing matching response for specified Accept header"}
That makes sense, since we aren't providing any response for that.
Unlike OpenAPI/Swagger 2.0, which has global consumes and produces, OpenAPI 3.0 requires that request and response media types be defined in each operation individually. There's no way to define the Content-Type or requests or responses globally.
You can, however, $ref common response definitions (such as error responses), which can reduce the repetition.
openapi: 3.0.2
...
paths:
/foo:
get:
responses:
'400':
$ref: '#/components/responses/ErrorResponse'
/bar:
get:
responses:
'400':
$ref: '#/components/responses/ErrorResponse'
components:
responses:
ErrorResponse:
description: An error occurred
content:
application/vnd.error+json:
schema:
...

Open API POST with Path Parameter

I am trying to write a Open API specification with Swagger-ui (swagger version 2.0) and I am not sure how to represent a POST parameter with a path parameter
POST /ping/{text}
My specification is as follows,
# this is an example of the Uber API
# as a demonstration of an API spec in YAML
swagger: '2.0'
info:
title: Mock API
description: Mock API
version: "1.0.0"
# the domain of the service
host: api.mock.com
# array of all schemes that your API supports
schemes:
- https
# will be prefixed to all paths
basePath: /v1
produces:
- application/json
paths:
/ping:
get:
summary: Ping
description: |
Respond to PING requests, similar to heart beat
parameters:
- name: path
in: path
description: String input for echo service
required: false
type: string
tags:
- ping
responses:
200:
description: The text passed in the request
schema:
type: string
default:
description: Empty response for request passed
schema:
type: string
And the swagger ui shows an error as follows -
code: "ONE_OF_MISSING"
message: "Not a valid parameter definition"
but if I change it to in: query the error vanishes. What am I doing wrong? or what is the right way to specify a path parameter in open API specification?
There are a few changes you need to make to your document to conform to the Open API specification.
1- The name field should match the path segment (ie text
If in is "path", the name field MUST correspond to the associated path segment from the path field in the Paths Object. See Path Templating for further information.
2- required: true should be added.
If the parameter is in "path", this property is required and its value MUST be true.
3- If you want to document POST /ping/{text}, get needs to be changed to post. Also the path segment (ie. /{text) should be added to the path.
Here is the final Swagger doc after the changes described above:
# this is an example of the Uber API
# as a demonstration of an API spec in YAML
swagger: '2.0'
info:
title: Mock API
description: Mock API
version: "1.0.0"
# the domain of the service
host: api.mock.com
# array of all schemes that your API supports
schemes:
- https
# will be prefixed to all paths
basePath: /v1
produces:
- application/json
paths:
/ping/{text}:
post:
summary: Ping
description: |
Respond to PING requests, similar to heart beat
parameters:
- name: text
in: path
description: String input for echo service
required: true
type: string
tags:
- ping
responses:
200:
description: The text passed in the request
schema:
type: string
default:
description: Empty response for request passed
schema:
type: string
According to the specification it seems that "required" has to be true if you set "in: path".
Details can be found here: http://swagger.io/specification/#parameterObject