How to set the Accept header globally in OpenAPI 3.0? - openapi

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:
...

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.

Why does SwaggerHub return error 403 when I test my OpenAPI definition?

I have the following OpenAPI definition hosted on SwaggerHub:
https://app.swaggerhub.com/apis/MyFirstAPI/1.0.1-oas3
openapi: 3.0.0
servers:
- url: http://api.myfirstapi.com/
info:
version: 1.0.1-oas3
title: Equ API
paths:
/query:
get:
tags:
- developers
parameters:
- in: query
name: searchString
schema:
type: string
responses:
'200':
description: search results matching criteria
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Equity'
'400':
description: There is 400
components:
schemas:
Equity:
...
When I test the GET /query request, it returns a 403 error:
content-length: 0
date: Fri,10 Sep 2021 14:32:54 GMT
server: nginx/1.18.0 + Phusion Passenger(R) 6.0.8
status: 403 Forbidden
via: 1.1 b5d86079363e9709b4c4051d3c94ac3d.cloudfront.net (CloudFront)
x-amz-cf-id: pYbLwlrEHg5DXkGe5FkysAjSjbSDqUg7Rrhbv-Dt8Xwt8JuPRMAW3Q==
x-amz-cf-pop: DEL54-C1
x-cache: Error from cloudfront
x-powered-by: Express,Phusion Passenger(R) 6.0.8
Why does this error happen and how to fix it?
This 403 error is somewhat misleading. The actual problem here is that the target server for requests - api.myfirstapi.com - does not actually exist. The servers list is supposed to specify your real server(s).
If you are designing a new API and don't have a live server yet, you can use SwaggerHub's mock server to similate responses and test API calls.
To add a mock to your API definition:
Click the API name on the editor toolbar.
Switch to the Integrations tab and click Add New Integrations.
Select API Auto Mocking from the list and click Add.
Enter any value for Name (e.g. mock), leave other options as is, and click Create and Execute.
Close the remaining dialogs.
This creates a mock server for your API and adds it to the servers list in your API definition:
servers:
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/OWNER_NAME/API_NAME/VERSION
Make sure to select this server in the API docs before you test API calls.

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

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

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
[...]

Rest API Token Based Authentication Mechanism with Swagger Not Working

I am trying to make an API call with rest token based authentication from swagger. But at server side, I don't find token in the request. I tried the same API call with poster and swagger. In Poster it works fine but in swagger it doesn't.
Below is my JSON file which I am using to make API call with token:
swagger: '2.0'
info:
title: City
description: City Information
version: 1.0.0
host: '127.0.0.1:8090'
schemes:
- http
basePath: /App
produces:
- application/json
paths:
/city/list:
get:
summary: city
description:
Show cities name and its attributes.
security:
- APIAuthKey: []
responses:
'200':
description: An array of city
default:
description: Unexpected error
securityDefinitions:
APIAuthKey:
type: apiKey
in: header
name: X-AUTH-TOKEN
And this is how swagger sends request with X-AUTH-TOKEN:
But, when I use the same API call wit same parameters and X-AUTH-TOKEN in Poster, It works fine. Below, I have highlighted that how I send request with Poster:
Can anyone please suggest if I'm doing anything wrong or missing something? Why am I unable to send token with request correctly to fetch at server side in request header?