openapi 3.0 - change from array to dictionary/hashmap - rest

This is basically the inventory example from Swagger Hub with a few items changed inside the array. Here is what the response looks like when I make a Python request to my SwaggerHub URL:
[{
"hostname": "server",
"ip_addr": "192.168.0.12",
"app_name": "generic",
"app_code": 12345678,
"xmx": "5678",
"jvm_version": "1.0.0",
"xms": "1234"
}]
How can I change the code so that it's a dictionary? I can't believe how many lines of YAML it takes to do what Flask or Falcon can do in about 5 lines of code.
Anyways, here is the template:
openapi: 3.0.0
# Added by API Auto Mocking Plugin
servers:
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/james_test/test/1.0.0
info:
description: This is a simple API
version: "1.0.0"
title: Simple Inventory API
contact:
email: you#your-company.com
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: admins
description: Secured Admin-only calls
- name: developers
description: Operations available to regular developers
paths:
/data:
get:
tags:
- developers
summary: get random data from james_test API
operationId: searchInventory
description: |
By passing in the appropriate options, you can search for
available inventory in the system
responses:
'200':
description: search results matching criteria
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/state_data'
'400':
description: bad input parameter
components:
schemas:
state_data:
type: object
required:
- app_code
- app_name
- jvm_version
- hostname
- ip_addr
- xms
- xmx
properties:
app_code:
type: integer
format: int64
example: 12345678
app_name:
type: string
example: generic
jvm_version:
type: string
format: string
example: '1.0.0'
hostname:
type: string
format: hostname
example: 'server'
ip_addr:
type: string
format: ipv4
example: '192.168.0.12'
xms:
type: string
format: string
example: '1234'
xmx:
type: string
format: string
example: '5678'
Thank you all.
Edit:
I was hoping to get the response like this:
{
"hostname": "server",
"ip_addr": "192.168.0.12",
"app_name": "generic",
"app_code": 12345678,
"xmx": "5678",
"jvm_version": "1.0.0",
"xms": "1234"
}

SwaggerHub mock server returns an array because your response is defined as an array:
content:
application/json:
schema:
type: array # <----
items:
$ref: '#/components/schemas/state_data'
To get an object response, use:
content:
application/json:
schema:
$ref: '#/components/schemas/state_data'

Related

How to add reference to application/x-www-form-urlencoded request body?

I have built the JSON request below which works fine. But how to provide the $ref if the request media type is application/x-www-form-urlencoded?
For example, you can see the schema Filters which I have created. I want to provide the reference to that in the NewDogRequest.Filter parameter.
openapi: 3.0.2
info:
description: RESTful web services for writing and reading Dogs Data.
version: v1.0
title: Dogs Services
tags:
- name: Dogs
paths:
/dogs:
post:
tags:
- Dogs
summary: Add new dogs data.
description: Use this service when you want to add a new dog.
operationId: addDog
requestBody:
$ref: '#/components/requestBodies/NewDogRequest'
responses:
200:
description: OK
content:
application/json:
schema:
type: string
components:
# ****************** Request Bodies ****************** #
requestBodies:
NewDogRequest:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
dogID:
description: >
* Unique dog id.
type: string
filter:
description: >
Specifies the type breed of the dog
type: string
enum:
- German Sheperd
- Husky
- DashHound
default: German Sheperd
# ****************** Schemas ****************** #
schemas:
Filters:
type: string
enum:
- German Sheperd
- Husky
- DashHound
default: German Sheperd
Tried the following, but it didn't work. If you see the image that I have attached the enums are not rendered in the html.
requestBodies:
NewDogRequest:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
dogID:
description: >
* Unique dog id.
type: string
filter:
description: >
Specifies the type breed of the dog
$ref: '#/components/schemas/Filters'
Swagger editor image

How do I generate a cut-down version of an OpenAPI spec YML (ex. petsore.yaml) using the file itself?

I'd like to use the OpenAPI generator to generate a cut-down version of a OpenAPI spec .yml to build a Postman-esque web application reading these cut-down versions.
Here's an example on what I try to get. I take the standard Petstore spec as an example:
Petstore:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
should generate a fairly similar cut-down spec file looking like this:
- url: /pets
method: GET
title: string
body: null
queryParameters:
- name: limit
defaultValue: 1
required: false
pathVariables: [ ]
- url: /pets/{{petId}}
method: GET
title: string
body: null
queryParameters: [ ]
pathVariables:
- name: petId
defaultValue: 1
required: true
- url: /pets
method: POST
title: string
body: "{ \"id\": \"1\", \"name\": \"Cathy\"}"
queryParameters: [ ]
pathVariables: [ ]
I never worked with mustache templates and didn't find any simple ELI5 tutorials of how to do that and if it's even possible, but I'd need that for multiple API specs as it would be too much of an effort to do and maintain it for every API manually.
How would I go about doing that? Is OpenAPI the right choice or should I go with something different?

How do I override example for specific properties in components in OpenAPI?

Here's the minimal working example:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
paths:
/pets:
get:
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
components:
schemas:
Pet:
type: object
required:
- customName
properties:
genericName:
type: string
example: Alex
customName:
type: string
example: Ivanov
I would like to use a component Pet for the spec above yet I would like to be able to override an example for customName (the reason is it's like a URL in my real example and I'd like it be specific and it's based on the current resource but the component itself is shared among multiple resources if that makes sense).
I tried #1:
...
application/json:
schema:
$ref: "#/components/schemas/Pet"
example:
customName: IvanovOverride
components:
...
application/json:
schema:
allOf:
- $ref: "#/components/schemas/Pet"
example:
properties:
customName: IvanovOverride
and #3:
schema:
allOf:
- $ref: "#/components/schemas/Pet"
- properties:
customName:
example: IvanovOverride
but they all didn't work on Swagger Editor (the doc always showed "Ivanov" as an example).
If you use OpenAPI 3.1, and you have the necessary tooling supporting it, you can use the $dynamicAnchor and $dynamicRef for solving the problem.
Example:
openapi: "3.1.0"
info:
version: 1.0.0
title: Swagger Petstore
paths:
/pets:
get:
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/PetWithFirstExampleName"
components:
schemas:
PetWithFirstExampleName:
properties:
customName:
example: firstExampleName
$dynamicAnchor: customNameExample
$ref: "#/components/schemas/Pet"
Pet:
type: object
$dynamicRef: customNameExample
required:
- customName
properties:
genericName:
type: string
example: Alex
customName:
type: string
# example is provided by the schema referenced by $dynamicRef
Note: this is a quite new feature of json schema and OpenAPI, so you can easily run into problems with the implementations.
Note 2: yours is an approximately similar usecase as this one in the official json schema test suite.

Validate OpenAPI response with dredd

I have an OpenAPI v3 specification file with the following (showing just fragments):
paths:
/global/name:
get:
description: Some description
tags:
- Global settings
operationId: getGlobalSettingsName
responses:
# Response code
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/globalSettingsName'
components:
schemas:
globalSettingsName:
type: object
properties:
name:
type: integer
description: 'ID'
example: 1
required:
- name
but the server response is:
{
"name": "somestring"
}
Note the name property type is integer and in the server response, it is a string (on purpose) but dredd request passes (success).
Doesn't dredd check for response property types?
I redefined the response as string (not JSON):
responses:
# Response code
'200':
description: Successful response
content:
application/json:
schema:
type: string
and dredd doesn't complain about either.
I even changed the property of the schema:
globalSettingsName:
type: object
properties:
www:
type: string
description: 'some description'
example: 'somestring'
required:
- www
And same (success) result when it is expected to fail.
Aren't these validation supported by dredd? Am I using specification wrong?
It results that the current version (8.0.5) only supports example value in content: https://github.com/apiaryio/dredd/issues/1281

REST API using a RAML specification: how to specify total-pages in response

I am not sure about how the REST API should be designed in terms of pagination.
Here's my example:
#%RAML 1.0
title: Test Api Documentation
description: Test Api Documentation
baseUri: https://localhost/
version: v0.1
protocols: [ HTTPS ]
mediaType: [ application/json ]
documentation:
- title: Test API for REST Client
content:
"Test API for REST Client."
types:
Thing:
type: object
properties:
name: string
age: number
color: string
Things:
type: object
properties:
things?: Thing[]
totalPages?:
type: integer
format: int64
/things:
get:
headers:
Cookie:
type: string
responses:
'200':
description: OK
body:
application/json:
type: Things
'401':
description: Unauthorized
'404':
description: Not Found
queryParameters:
page:
description: page
required: false
type: integer
format: int32
pageSize:
description: pageSize
required: false
type: integer
format: int32
There is this wrapper type 'Things' to be able to add the totalpages property for the response.
Is this the right way how to do it?
I've also read that a custom http header can be used (x-total-pages or something like that).
I actually kind of don't like to have all the wrapper types in the API...
Does anybody know which is the standard for this?
Thanks a lot in advance for your answers.
Sergio
You can encapsulate all the paginated traits into a trait and use that across all you pageable reosources using is. As pageable resource are typically GET /collectionresource, you can also add a trait for the response header X-TOTAL-PAGES for 200 responses that are paginated.
Example:
#%RAML 1.0
baseUri: https://mocksvc.qax.mulesoft.com/mocks/8ab3d909-11e0-4f1d-aaef-bef029b83fbf
title: paginated api
mediaType: application/json
protocols: [ HTTP ]
traits:
paginated:
queryParameters:
page:
description: page
required: false
type: integer
format: int32
pageSize:
description: pageSize
required: false
type: integer
format: int32
responses:
200:
headers:
x-total-pages:
types:
Thing:
type: object
properties:
name: string
age: number
color: string
Things:
type: object
properties:
things?: Thing[]
/things:
get:
is: [ paginated ]
responses:
'200':
description: OK
body:
application/json:
type: Things
'401':
description: Unauthorized
'404':
description: Not Found