How to pass array of string in swagger form data field - node.js

I want to pass an array inside form data like below:
but I am getting the whole array as a string in NodeJS console like this:
{
targetUniversity: "['613e3ecfefa725074cb17968', '613e3ecfefa725074cb17969']",
targetBusinessType: "['freelancer','sw dev']",
}
The swagger file looks something like this,
"/announce": {
"post": {
"tags": ["Announcement"],
"description": "Make an announcement",
"parameters": [
{
"name": "targetUniversity",
"in": "formData",
"type": "array",
"description": "University ID in array []- from DD"
},
{
"name": "targetBusinessType",
"in": "formData",
"type": "array",
"description": "Business type (string - name) in array []"
}
],
"produces": ["application/json"],
"responses": {
"201": {
"description": "announced successfully"
}
}
}
}
I just want the array itself, not the array in string format.

Array parameters need the items keyword to define the type of array items. Also, the operation must specify what MIME type(s) it consumes:
"consumes": [
"application/x-www-form-urlencoded"
],
"parameters": [
{
"name": "targetUniversity",
"in": "formData",
"type": "array",
"items": { // <------
"type": "string"
},
"description": "University ID in array []- from DD"
},
{
"name": "targetBusinessType",
"in": "formData",
"type": "array",
"items": { // <------
"type": "string"
},
"description": "Business type (string - name) in array []"
}
],
In Swagger UI, enter the array items one per line and without quotes:

You can specify arrays in OAS3 as follows;
"parameters": [
{
"name": "targetUniversity",
"in": "formData", -->> according to comments this should be replaced by requestBody in OAS3
"schema": {
"type": "array",
"items": {
"type": "string"
}
...
The result will be like;

Related

Swagger OpenAPI describing string array in multipart request

I need to describe a multipart query that has an array of strings. But I ran into a problem, in the query, the array elements are combined into one string instead of being separate string items. I am using OpenApi 3.0.3
"multipart/form-data": {
"schema": {
"type": "object",
"required": ["image"],
"properties": {
"image": {
"type": "string",
"format": "base64",
"description": "Banner image `1920x90, 2mb`"
},
"name": {
"type": "string",
"example": "Docs banner",
"description": "Banner name"
},
"link": {
"type": "string",
"description": "Banner link"
},
"page[]": {
"type": "array",
"items": {
"type": "string"
},
"example": ["HOME", "LIVE", "CHANNELS"],
"enum":[
"HOME",
"LIVE",
"CHANNELS",
"ARTISTS",
"DISCOVER",
"MYLIST",
"PROGRAM",
"PLAYER"
],
"description":"Banner pages"
}
}
}
}
What I received: page: [ 'HOME,LIVE,CHANNELS' ]
What I expect: page: [ 'HOME','LIVE','CHANNELS' ]
It's not very clear where exactly do you receive page: [ 'HOME,LIVE,CHANNELS' ], but looks like in enum there are possible values for items of your array. Try this:
"multipart/form-data": {
"schema": {
"type": "object",
"required": ["image"],
"properties": {
"image": {
"type": "string",
"format": "base64",
"description": "Banner image `1920x90, 2mb`"
},
"name": {
"type": "string",
"example": "Docs banner",
"description": "Banner name"
},
"link": {
"type": "string",
"description": "Banner link"
},
"page[]": {
"type": "array",
"items": {
"type": "string",
"enum":[
"HOME",
"LIVE",
"CHANNELS",
"ARTISTS",
"DISCOVER",
"MYLIST",
"PROGRAM",
"PLAYER"
],
"example": "HOME"
},
"example": [ "HOME", "LIVE", "CHANNELS" ],
"description":"Banner pages"
}
}
}
}
You can look for more details at the specification for adding examples.
This structure allows you to send multiple string enum items for page element, screenshot from swagger editor is below:

JSON schema validation Draft 7 two type of data for one field

I need help creating a JSON schema for a value that could be an object, or an array of objects.
lib: jsonschema==3.2.0
py: 3.8
I have 2 responses from the server:
first:
{
"result": [
{
"brand": "Test"
}
]}
second:
{
"result":
{
"brand": "Test"
}
}
As you can see the difference between both in the first case its an array of obj the second just object.
my schema:
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"$id": "#/properties/result",
"type": ["array", "object"],
"additionalItems": true,
"items": {
"$id": "#/properties/result/items",
"anyOf": [
{
"$id": "#/properties/result/items/anyOf/0",
"type": "object",
"required": [
"brand"
],
"properties": {
"brand": {
"$id": "#/properties/result/items/anyOf/0/properties/brand",
"type": "string"
}
},
"additionalProperties": true
}
]
}
}
},
"additionalProperties": true}
In the first case when return array, it checks the "brand" type on the second when return object, no.
How I can set up 2 types for one field "result" that it could check the brand type?
Your schema can be fixed as follows:
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"$id": "#/properties/result",
"anyOf": [
{
"$id": "#/properties/result/items/brand",
"type": "object",
"properties": {
"brand": {
"$id": "#/properties/result/items/anyOf/0/properties/brand",
"type": "string"
}
},
"required": [
"brand"
],
"additionalProperties": true
},
{
"$id": "#/properties/result/items/array",
"type": "array",
"items": {
"$ref": "#/properties/result/items/brand"
}
}
]
}
},
"additionalProperties": true
}
Demos here, here and here.
However, it is customary to extract reusable portions of a schema into a separate "definitions" section, like so:
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"definitions": {
"brand": {
"type": "object",
"properties": {
"brand": {
"$id": "#/properties/result/items/anyOf/0/properties/brand",
"type": "string"
}
},
"required": [
"brand"
],
"additionalProperties": true
}
},
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"$id": "#/properties/result",
"anyOf": [
{
"$ref": "#/definitions/brand"
},
{
"$id": "#/properties/result/items/array",
"type": "array",
"items": {
"$ref": "#/definitions/brand"
}
}
]
}
},
"additionalProperties": true
}
Demos here, here and here.
Notes:
To express that the property "result" may be of two different types, use the "anyof" keyword for the property's schema. The value of the "anyOf" should be an array with the schemas for each possible type (here the "brand" object or an array of "brand" objects) as the array items.
See: Multiple Types.
To avoid duplicating the definitions for the "brand" object, you can use the "$ref" when defining a schema for the array's items to refer back to the previously given schema for "brand". As noted above it s customary to place reused subschemas into a "definitions" section, but it is not necessary, "$ref" can refer to any schema item via the JSON Pointer syntax.
See: Reuse.
When the items of a list have a single schema, "additionalItems" should not be used.
See: List validation.

how to access json within http trigger

How do I get the subject property from the payload below ?
I've got an http-triggered logic app:
I want to be able to grab the contents of the subject property.
The schema as shown above in the image looks like this:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"topic": {
"type": "string"
},
"subject": {
"type": "string"
},
"eventType": {
"type": "string"
},
"eventTime": {
"type": "string"
},
"id": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"api": {
"type": "string"
},
"clientRequestId": {
"type": "string"
},
"requestId": {
"type": "string"
},
"eTag": {
"type": "string"
},
"contentType": {
"type": "string"
},
"contentLength": {
"type": "integer"
},
"blobType": {
"type": "string"
},
"url": {
"type": "string"
},
"sequencer": {
"type": "string"
},
"storageDiagnostics": {
"type": "object",
"properties": {
"batchId": {
"type": "string"
}
}
}
}
},
"dataVersion": {
"type": "string"
},
"metadataVersion": {
"type": "string"
}
},
"required": [
"topic",
"subject",
"eventType",
"eventTime",
"id",
"data",
"dataVersion",
"metadataVersion"
]
}
}
How do I get the subject property from this payload?
Go to your logic app designer in the azure portal and you can specifically assign the json to variables in your flow process
Here is the link on how to do this
With the Request trigger, if you want to get the property, you need pass the Request Body into json cause the triggerBody() value is in a String type, it doesn't support select the property. Set the parse json action like the below pic.
Then your json set the data in array type, that's another problem you will encounter. So when you select property you need add the index like the below with Expression: body('Parse_JSON')[0]['subject'].
I test with short json two properties subject and topic.

Missing Subscription Key field in Swagger API connector (trough Azure API Management) in Logic App

I have created a REST API with a Swagger/OPEN API specification which I will like to consume trough a Azure API Management tenant in a Logic App.
When I download the specification it looks like this:
{
"swagger": "2.0",
"info": {
"title": "Leasing",
"version": "1.0"
},
"host": "ENDPOINT.azure-api.net",
"basePath": "/leasing",
"schemes": [
"http",
"https"
],
"securityDefinitions": {
"apiKeyHeader": {
"type": "apiKey",
"name": "Ocp-Apim-Subscription-Key",
"in": "header"
},
"apiKeyQuery": {
"type": "apiKey",
"name": "subscription-key",
"in": "query"
}
},
"security": [
{
"apiKeyHeader": []
},
{
"apiKeyQuery": []
}
],
"paths": {
"/{Brand}/groups": {
"get": {
"description": "Get a list of leasing groups on a brand",
"operationId": "GetGroups",
"parameters": [
{
"name": "Brand",
"in": "path",
"description": "Selection of possible brands",
"required": true,
"type": "string",
"enum": [
"Volkswagen",
"Audi",
"Seat",
"Skoda",
"VolkswagenErhverv",
"Porsche",
"Ducati"
]
}
],
"responses": {
"200": {
"description": "Returns a list of leasing groups",
"schema": {
"$ref": "#/definitions/GroupArray"
}
},
"400": {
"description": "If the brand is not valid",
"schema": {
"$ref": "#/definitions/Error"
}
}
},
"produces": [
"application/json"
]
}
}
},
"definitions": {
"Group": {
"type": "object",
"properties": {
"id": {
"format": "int32",
"type": "integer"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"leasingModelCount": {
"format": "int32",
"type": "integer"
},
"lowestMonthlyFee": {
"format": "int32",
"type": "integer"
}
}
},
"Error": {
"type": "object",
"properties": {
"code": {
"enum": [
"NotValidBrand",
"NotValidGroupId"
],
"type": "string",
"x-ms-enum": {
"name": "ErrorCode",
"modelAsString": true
}
},
"message": {
"type": "string"
}
}
},
"GroupArray": {
"type": "array",
"items": {
"$ref": "#/definitions/Group"
}
}
}
}
When I add this in a Logic App with the connector HTTP + Swagger I only get to define the {Brand} query input but not the various ways of using the Subscriptions key (header or query) as defined in SecurityDefiniations.
The whole securityDefinitions and security section are automatically generated in the Azure API Management service, but not recognized in Logic App.
See image of missing subscription key field:
What am I doing wrong?
Update
I have tried the following:
Usage of the 'Authentication' field (but this field is limited to certain types of auths flows https://learn.microsoft.com/en-us/azure/connectors/connectors-native-http#authentication)
Change the Logic App 'Http + Swagger'-action in code to add the header parameter, but this action converts the action to a simple 'Http' action and therfore loosing the automatic schema generation from Swagger.
I think you need to specify this in the Authentication-field in a JSON format. Something like:
{
"apiKeyHeader" : "your Ocp-Apim-Subscription-Key",
"apiKeyQuery" : "your subscription key"
}

Is it possible to define a parameter set and reference it?

I have multiple parameters that I want to reference, but I do not want to specify them one by one.
This snippet does not make the parameters show up:
{
...
"paths": {
"/stuff": {
"get": {
"description": "Gets stuff",
"operationId": "getStuff",
"parameters": {
"$ref": "#/definitions/set1"
}
}
}
},
"parameters": {
"a": {
"name": "a",
"in": "query",
"description": "Param A",
"required": false,
"type": "string"
},
"b": {
"name": "b",
"in": "query",
"description": "Param B",
"required": false,
"type": "string"
}
},
"definitions": {
"set1": [
{
"$ref": "#/parameters/a"
},
{
"$ref": "#/parameters/b"
}
],
"set2": ...
}
}
Is this possible or do I have to specify each parameter like set1, for each request?
Indeed that's not a valid definition and as you suggested, you'd have to specify each parameter separately by referencing the global one. If your parameters are shared for all operations under a specific path, you can define those at the path level and they would be applied to all operations.
For an individual operation, you'd define it as:
"paths": {
"/stuff": {
"get": {
"description": "Gets stuff",
"operationId": "getStuff",
"parameters": [
{
"$ref": "#/parameters/a"
},
{
"$ref": "#/parameters/b"
}
]
}
}
}

Resources