How to set up Swagger with express? - coffeescript

I am using the {swagger-express} library and my code is all in CoffeeScript. For my definition, I have:
app.use swagger.init app,
apis: ['./src/routes.coffee', './src/models.yml']
apiVersion: '0.1.0'
basePath: "http://localhost:#{port}"
info:
title: 'My API'
description: 'A complete listing of all API functions'
swaggerUI: path.join __dirname, 'public'
swaggerURL: '/swagger'
require('./src/routes') app
In routes, I have:
###
* #swagger
* path: /login
* operations:
* - httpMethod: POST
* summary: Login with username and password
* notes: Returns a user based on username
* responseClass: User
* nickname: login
* consumes:
* - text/html
* parameters:
* - name: username
* description: Your username
* paramType: query
* required: true
* dataType: string
* - name: password
* description: Your password
* paramType: query
* required: true
* dataType: string
###
and that works fine. My model.yml file is:
definitions:
User:
properties:
user_id:
type: string
description: Unique ID to represent the user
first_name:
type: string
description: First name of the Uber user.
last_name:
type: string
description: Last name of the Uber user.
email:
type: string
description: Email address of the Uber user
picture:
type: string
description: Image URL of the Uber user.
promo_code:
type: string
description: Promo code of the Uber user.
But that doesn't show up in the api-docs.json. I am trying to define the models in one file and the paths in another. Can that be done?

I don't think it will work because each format is read separately and saved in a hash which is uses the resourcePath as the key.
https://github.com/fliptoo/swagger-express/blob/a5560af936e5398affe36d347af5be2a1bb64fc2/lib/swagger-express/index.js#L27
Any further declaration of the same resourcePath will override the previous declaration.
I tested with an updated yml format with a resourcePath, the name models instead of definitions and a unique id for the model. This made the models show up but none of my other information :/
resourcePath: /login
models:
User:
id: User
properties:
user_id:
type: String
description: Unique ID to represent the user
first_name:
type: String
description: First name of the Uber user.
last_name:
type: String
description: Last name of the Uber user.
email:
type: String
description: Email address of the Uber user
picture:
type: String
description: Image URL of the Uber user.
promo_code:
type: String
description: Promo code of the Uber user.
The example on their github makes it look like this will work but I couldn't make it work.

Related

Referencing Column in Different Schema for One-to-One Relationship in OpenAPI 3.1

I'm working with two schemas User and Post. User has fields username, bio, email, and password and Post has fields username, text, and timestamp.
I want to associate field username in Post with field username in User. They will be in a one-to-one relationship.
I have come up with the below specification:
components:
schemas:
Post:
type: object
required:
- username
- text
discriminator:
propertyName: username
mapping:
username: '#/components/schemas/User'
properties:
username:
description: Username of the person who posted
type: string
text:
description: Contents of the post
type: string
timestamp:
description: ISO-8601 timestamp of when the post was made
type: string
format: date-time
User:
type: object
required:
- username
- bio
- email
- password
properties:
username:
description: Username for user
type: string
$ref: '#/components/schemas/Post'
bio:
description: Profile headline
type: string
email:
description: User's email address for notifications and security updates
type: string
password:
description: User's password for login
type: string
Is this correct ?

How to define a path with two optional parameters in OpenAPI 3.0?

I registered at SwaggerHub and created a new API using OpenAPI 3.0. In my API, the /tasks path has 2 non-required parameters, but I can not set them as not required - the editor shows the "Not allowed Values" error.
Here's my API definition:
openapi: 3.0.0
info:
description: A Simple IP Address API
title: VTasks
version: v1
servers:
# Added by API Auto Mocking Plugin
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/petrogromovo/Vtasks/1.0.0
- description: SwaggerHub API Auto Mocking
url: http://hosting.tk
paths:
/tasks:
get:
tags:
- tasks
summary: Get paginated / filtered tasks listing
operationId: tasks
parameters:
- name: page
in: path
description: The page number to be fetched. If missed default 1.
required: true
schema:
type: integer
- name: order_by
in: path
description: The order_by be fetched.
required: false // ERROR : should be equal to one of the allowed values allowedValues: true
schema:
type: string
- name: filter
in: path
description: The filter for title field.
required: false // ERROR : should be equal to one of the allowed values allowedValues: true
schema:
type: string
responses:
'200':
description: successful operation
'400':
description: Invalid tasks supplied
'404':
description: tasks were not found
But if I remove the required attributes, I get 2 errors:
should have required property 'required'
missingProperty: required
What is the valid syntax?
Are these parameters supposed to be path parameters or query parameters?
Path parameters (in: path) are part of the endpoint path, and as such must be indicated by {...} in the path template:
paths:
/tasks/{page}/{order_by}/{filter}:
Path parameters are always required, i.e. they must have required: true.
Query parameters are send in the query string, e.g. /tasks?page=...&order_by=.... To use query parameters, change the parameter location to in: query.
More information: Describing Parameters

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

How to use the same definition for an ID parameter and an ID schema property?

I am wondering if there is a way in OpenAPI to describe that the user_id used as a path parameter is the same type of value as the id field of a User object. A benefit of this is reusing the description and example.
openapi: 3.0.1
info:
title: Test API
version: 1.0.0
paths:
/foo/{user_id}:
get:
parameters:
- $ref: '#/components/parameters/user_id'
responses:
'200':
description: A user
content:
application/json:
schema:
$ref: '#/components/schemas/User'
components:
parameters:
user_id:
name: user_id
in: path
required: true
description: the id of a User, from parameters
example: ghijkl
schema:
type: string
schemas:
User:
type: object
properties:
id:
type: string
description: the id of a User, from schemas
example: abcdef
I don't like having to re-define the example and description of the user ID.
You can define a separate schema for the user ID and have the parameter/property schema reference the user ID schema:
components:
parameters:
user_id:
name: user_id
in: path
required: true
schema:
$ref: '#/components/schemas/UserId' # <-------
schemas:
UserId:
type: string
description: The ID of a User
example: abcdef
User:
type: object
properties:
id:
$ref: '#/components/schemas/UserId' # <-------
Swagger Editor and Swagger UI will fetch the parameter example from the schema example, but the parameter description is currently not fetched from the schema description. Feel free to submit an enhancement request.

openapi 3.0 - change from array to dictionary/hashmap

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'