Closed brooksyott closed 6 years ago
Hey @brooksyott , thanks for the taking the time to report the issue. The problem you are running into is that the examples
property in a media type object is a map and not an array. This was changed from v2, where it used to be an array. Also, now the examples object allows you to specify some metadata about the example.
Perhaps I gave a bad example. I may still be misunderstanding as well.
I believe from the openApi page on Swagger: https://swagger.io/docs/specification/adding-examples/
The following should work:
openapi: "3.0.0"
info:
description: API for CPaaS 2.0 to use SMS related functions
version: "0.2"
title: CPaaS SMS API
termsOfService: https://kandy.io
contact:
name: Kandy CPaaS API Team
email: no.email@kandy.io
url: https://kandy.io
servers:
- url: https://cpaas-api20-kvs1.kandy.io/{cpaasRoot}/
variables:
cpaasRoot:
default: cpaas
description: Root folder name configured based on the deployment
paths:
/smsmessaging/{apiVersion}/{userId}/inbound/subscriptions:
parameters:
- in: query
name: limit
schema:
type: integer
maximum: 50
examples: # Multiple examples
zero: # Distinct name
value: 0 # Example value
summary: A sample limit value # Optional description
max: # Distinct name
value: 50 # Example value
summary: A sample limit value # Optional description
When I put that into the workbench (or use the library), I get: Failed to parse input: Unable to cast object of type 'Microsoft.OpenApi.Readers.ParseNodes.MapNode' to type 'Microsoft.OpenApi.Readers.ParseNodes.ListNode'.
If I change "examples" to "example", it does convert it without error?
@brooksyott Yes, your example above should work. There is an error in the library. I will get that fixed ASAP. Thanks for the heads up.
The reason it works when you change to example
is because we accept any structure under example, but that is not what you are trying to do in this case.
Really appreciate the quick response, thank you!!
If you use the keyword "examples:", either in JSON or YAML, it fails. In the case of YAML, an exception is thrown. In the case of JSON,
Cannot create map at #/paths//smsmessaging/{apiVersion}/{userId}/inbound/subscriptions/get/responses/200/content/examples
and it omits it from the conversion.
I used the OpenAPI workbench to validate my findings.
Sample JSON that fails below:
{ "openapi": "3.0.0", "info": { "title": "CPaaS SMS API", "description": "API for CPaaS 2.0 to use SMS related functions", "termsOfService": "https://kandy.io", "contact": { "name": "Kandy CPaaS API Team", "url": "https://kandy.io", "email": "fatih.demirel@kandy.io" }, "version": "0.2" }, "servers": [ { "url": "https://cpaas-api20-kvs1.kandy.io/{cpaasRoot}/", "variables": { "cpaasRoot": { "default": "cpaas", "description": "Root folder name configured based on the deployment" } } } ], "paths": { "/smsmessaging/{apiVersion}/{userId}/inbound/subscriptions": { "get": { "tags": [ "inboundSMS" ], "summary": "Read all active inbound SMS subscriptions", "description": "Read all active inbound SMS subscriptions", "operationId": "readAllInboundSMSSubscription", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/inboundAllSMSSubscriptionResponse" }, "examples": [ { "inboundAllSMSSubscriptionResponseExample": {
"$ref": "#/components/examples/inboundAllSMSSubscriptionResponseExample" } }, { "inboundAllSMSSubscriptionResponseExample": {
"$ref": "#/components/examples/inboundAllSMSSubscriptionResponseExample" } } ] } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/failureResponse" } } } } } }, "parameters": [ { "$ref": "#/components/parameters/apiVersion" }, { "$ref": "#/components/parameters/userId" } ] } }, "components": { "schemas": { "serviceException": { "type": "object", "properties": { "messageId": { "type": "string", "description": "Error response ID" }, "text": { "type": "string", "description": "Detailed explanation of the error condition" }, "variables": { "type": "array", "items": { "type": "string", "description": "Varible values appear within the text field" } } } }, "link": { "type": "object", "properties": { "href": { "type": "string", "description": "Relative path to the resource being called" }, "rel": { "enum": [ "smsmessaging" ], "type": "string" } } }, "requestError": { "type": "object", "properties": { "link": { "$ref": "#/components/schemas/link" }, "serviceException": { "$ref": "#/components/schemas/serviceException" } } }, "failureResponse": { "type": "object", "properties": { "requestError": { "$ref": "#/components/schemas/requestError" } } }, "callbackReference": { "required": [ "notifyURL" ], "type": "object", "properties": { "notifyURL": { "type": "string", "description": "The notification channel ID that has been acquired during /notificationchannel API subscription, either websocket or mobile push type, which the incoming notifications supposed to be sent to." } } }, "inboundSMSSubscriptionReq": { "required": [ "callbackReference", "clientCorrelator" ], "type": "object", "properties": { "callbackReference": { "$ref": "#/components/schemas/callbackReference" }, "clientCorrelator": { "$ref": "#/components/schemas/clientCorrelator" }, "destinationAddress": { "type": "string", "description": "The address that incoming messages are received. Current implementation assumes this value is the same with the {userId} path parameter." } } }, "inboundSMSSubscriptionResp": { "allOf": [ { "$ref": "#/components/schemas/inboundSMSSubscriptionReq" }, { "type": "object", "properties": { "resourceURL": { "$ref": "#/components/schemas/resourceURL" } } } ] }, "inboundSMSSubscriptionResponse": { "type": "object", "properties": { "subscription": { "$ref": "#/components/schemas/inboundSMSSubscriptionResp" } } }, "inboundSMSAllSubscriptionResp": { "type": "array", "items": { "$ref": "#/components/schemas/inboundSMSSubscriptionResp" } }, "resourceURL": { "type": "string", "description": "Relative path of the resource" }, "subscriptionList": { "type": "object", "properties": { "resourceURL": { "$ref": "#/components/schemas/resourceURL" }, "subscription": { "$ref": "#/components/schemas/inboundSMSAllSubscriptionResp" } } }, "inboundAllSMSSubscriptionResponse": { "type": "object", "properties": { "subscriptionList": { "$ref": "#/components/schemas/subscriptionList" } } }, "NotificationChannelRequest": { "required": [ "notificationChannel" ], "type": "object", "properties": { "notificationChannel": { "oneOf": [ { "$ref": "#/components/schemas/NotificationChannelWSReq" }, { "$ref": "#/components/schemas/NotificationChannelPushReq" } ] } } }, "NotificationChannelWSReq": { "required": [ "channelType", "clientCorrelator" ], "type": "object", "properties": { "applicationTag": { "$ref": "#/components/schemas/applicationTag" }, "channelLifetime": { "type": "integer", "description": "Indicates the channelLifetime value requested, in seconds." }, "channelType": { "enum": [ "Websockets" ], "type": "string" }, "clientCorrelator": { "$ref": "#/components/schemas/clientCorrelator" }, "x-connCheckRole": { "$ref": "#/components/schemas/x-connCheckRole" } } }, "NotificationChannelPushReq": { "required": [ "channelData", "channelType", "clientCorrelator" ], "type": "object", "properties": { "applicationTag": { "$ref": "#/components/schemas/applicationTag" }, "channelData": { "$ref": "#/components/schemas/ChannelDataPush" }, "channelType": { "enum": [ "OMAPush" ], "type": "string" }, "clientCorrelator": { "$ref": "#/components/schemas/clientCorrelator" } } }, "ChannelDataPush": { "type": "object", "properties": { "appId": { "type": "string", "description": "Defines application bundle ID on FCM\APNS" }, "x-deviceToken": { "type": "string", "description": "Indicates the token provided by Push provider (FCM\APNs)" }, "x-provider": { "enum": [ "apns", "fcm" ], "type": "string", "description": "Indicates which Push provider to be used" } } }, "x-connCheckRole": { "enum": [ "client", "server" ], "type": "string", "description": "Optional param, indicates if client wants to use application level websocket ping-pong (connCheck-connAck), and in which role the client desires to take." }, "clientCorrelator": { "type": "string", "description": "Indicates a unique ID for the client being used, where same ID should be provided for WebSocket, Push and other CPaaS services subscriptions and REST requests generated from the same device and application for correlation purposes." }, "applicationTag": { "type": "string", "description": "An optional tag for the application, not being used by CPaaS." } }, "parameters": { "apiVersion": { "name": "apiVersion", "in": "path", "description": "API version", "required": true, "schema": { "type": "string" }, "example": { "NotificationChannelResponseExample-WS": "", "$ref": "#/components/examples/NotificationChannelResponseExample-WS" } }, "subscriptionId": { "name": "subscriptionId", "in": "path", "description": "Resource ID of the subscription", "required": true, "schema": { "type": "string" } } } }, "tags": [ { "name": "inboundSMS", "description": "Resources related with inbound SMS subscription" } ] }