Swagger array of objects - arrays

I am having some issues with swagger: I have an array of objects (address) described in this way in the .yaml file:
Address:
properties:
street:
type: string
city:
type: string
state:
type: string
country:
type: string
and this is the other yaml file with the definitions of the API (address is a params):
- name: addresses
in: formData
description: List of adresses of the user. The first one is the default one.
type: array
items:
$ref: '#/definitions/Address'
And this is the text I put in the swagger UI:
[
{
"street": "Bond street",
"city": "Torino",
"state": "Italy",
"country": "Italy"
}
]
but in node.js, if I print what I receive:
{"addresses":["["," {"," \"street\": \"Bond street\",","
\"city\": \"Torino\","," \"state\": \"Italy\","," \"country\":
\"Italy\""," }","]"]}
And I get a parsing error... There are some extra [ and ". It seems that swagger parse it as string (?)

To send JSON data, you need to use use an in: body parameter (not in: formData) and specify that the operation consumes application/json. formData parameters are used for operations that consume application/x-www-form-urlencoded or multipart/form-data.
paths:
/something:
post:
consumes:
- application/json
parameters:
- in: body
name: addresses
required: true
schema:
type: array
items:
$ref: "#/definitions/Address" # if "Address" is in the same file
# or
# $ref: "anotherfile.yaml#/definitions/Address" # if "Address" is in another file

Related

How to write multiple JSON array objects in openapi yaml file from JSON body? [duplicate]

I am using Swagger OpenAPI Specification tool. I have a string array property in one of the definitions as follows:
cities:
type: array
items:
type: string
example: "Pune"
My API produces JSON result, so Swagger UI displays the following example for the response:
{
"cities": [
"Pune"
]
}
How can I add multiple example values for the cities array? Expecting the result as:
{
"cities": [
"Pune",
"Mumbai",
"Bangaluru"
]
}
Tried comma-separated strings in the example key like below:
cities:
type: array
items:
type: string
example: "Pune", "Mumbai", "Bangaluru"
But the Swagger Editor shows an error, "Bad indentation".
Is there any way to specify multiple values in the example key?
Update
User Helen below has given the correct answer. I had an indentation problem hence there were nested arrays (2d arrays)
Correct way:
cities:
type: array
items:
type: string
example:
- Pune
- Mumbai
My way (which was wrong)
cities:
type: array
items:
type: string
example:
- Pune
- Mumbai
Look for the indentation of the example key in the above two cases which makes the difference, its YAML indentation matters.
To display an array example with multiple items, add the example on the array level instead of item level:
cities:
type: array
items:
type: string
example:
- Pune
- Mumbai
- Bangaluru
# or
# example: [Pune, Mumbai, Bangaluru]
In case of array of objects, the example would look like this:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string
example:
- id: 1
name: Prashant
- id: 2
name: Helen
paths:
/products_1:
get:
responses:
'200':
description: "XYZ"
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/pro'
example:
- name : "Laptop"
dist : "HP LAPTOP"
- name : "Mobile"
dist : "Apple Mobile"
components:
schemas:
pro:
type: object
properties:
prodName:
type: string
example: "Laptop"
prodDesc:
type: string
example: "Produc Description"
For openapi version - 3.0.0+
major:
type: array
items:
type: string
enum:
- Accounting
- Business Contacts
- Economy
- Finance
- Graphic Design
- International Business Administration
- International Relations
- Law
- Marketing
- others
- Political Science
- Statistics

Google Cloud Api Gateway - {"message":"no healthy upstream","code":503}

I am building an api that is hosted on App Engine Standard (Python).
I have test it with curl and I was able to make a successfully post request:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"amount":xxxx,"currency":"xxx","date":xxxx,"name":"xxxx","symbol":"xxx"}' \
https://xxxxxxxxxx.appspot.com/api/add/
Then I deployed an Api Gateway to access my App Engine Standard back end.
Getting started with API Gateway and App Engine
I tested and it worked fine for GET requests.
Now I am having issue performing a POST request. This is my code from config.yaml file:
/add:
post:
summary: Creates a new transaction.
operationId: create-transaction
consumes:
- application/json
parameters:
- in: body
name: transaction
description: The transaction to create.
schema:
type: object
required:
- name
symbol
currency
amount
date
properties:
name:
type: string
symbol:
type: string
currency:
type: string
amount:
type: number
date:
type: integer
x-google-backend:
address: https://xxxxxxx.appspot.com
path_translation: [ APPEND_PATH_TO_ADDRESS ]
jwt_audience: 272804158038-6kc250fms52o33b7dcfjrl1f9d8rripb.apps.googleusercontent.com
responses:
'201':
description: A successful transaction created
schema:
type: string
When I am trying to run the same curl command :
curl --header "Content-Type: application/json"
--request POST
--data '{"amount":xxxx,"currency":"xxx","date":xxxx,"name":"xxxx","symbol":"xxxx"}'
https://saxxx-xxxxxxx-gateway.dev/add/
I receive :
{"message":"no healthy upstream","code":503}
Can somebody please help me troubleshooting this error message ? Again, I am able to run successfully GET requests on the same Gateway.
This is the log I found on Logging :
{
httpRequest: {
latency: "0s"
protocol: "http"
remoteIp: ""
requestMethod: "POST"
requestSize: "936"
requestUrl: "/add"
responseSize: "158"
status: 503
}
insertId: ""
jsonPayload: {
api_key_state: "NOT CHECKED"
api_method: "1.xxxxxx_2ere0etrrw81sxxxxxxxxxxxxxx_cloud_goog.Createtransaction"
api_name: "1.xxxxxxxxxxx_api_2exxxxxx_cloud_goog"
api_version: "1.0.0"
location: ""
log_message: "1.sxxxxxxxxxxx.Createtransaction is called"
producer_project_id: "xxxxxx"
response_code_detail: "no_healthy_upstream"
service_agent: "ESPv2/2.21.0"
service_config_id: "sxxxxxxxx4jvuvmlcb"
timestamp: 1616270864.269634
}
logName: "projects/sagexxxxxxxx.apigateway.xxxxxxxxx.cloud.goog%2Fendpoints_log"
receiveTimestamp: "2021-03-20T20:07:46.372838475Z"
resource: {
labels: {
location: ""
method: "1.xxxxxxxxxxxx_goog.Createtransaction"
project_id: ""
service: "xxxxxxxxxxxxx.cloud.goog"
version: "1.0.0"
}
type: "api"
}
severity: "ERROR"
timestamp: "2021-03-20T20:07:44.269633934Z"
}
I had a problem with my config.yaml file code:
/add:
post:
summary: Creates a new transaction.
operationId: create-transaction
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: body
required: false
schema:
$ref: '#/definitions/Model0'
x-google-backend:
address: https://appspot.com
path_translation: [ APPEND_PATH_TO_ADDRESS ]
jwt_audience: .googleusercontent.com
responses:
'201':
description: A successful transaction created
schema:
type: string
definitions:
Model0:
properties:
amount:
type: number
format: double
currency:
type: string
date:
type: integer
format: int64
name:
type: string
symbol:
type: string

Wiremock - how to match all permutations of array elements of a multipart/form-data in JSON?

I'm trying to mock a YAML API using JSON Wiremock for a PUT multipart/form-data. The multipart contains two arrays of metadata. How can I match a set of specific values (or regex) in each array, disregarding of the order.
We are bound to use YAML 2.0 (if you wonder), which is why we have these two arrays for the metadata. I've been able to successfully match specific values for the array (for example, for fileMetadataName, I can match "permissions,owner"), but I haven't found how to match the full set of potential values (5 values with all possible permutations, see YAML below).
Here is the JSON Wiremock file that can match one case of the array:
{
"request": {
"method": "PUT",
"urlPath": "/files",
"headers": {
"Content-Type": { "contains": "multipart/form-data"},
"Source": { "matches": "POC(.+)"}
},
"multipartPatterns": [
{
"headers": {
"Content-Disposition": {
"contains": "name=\"typeOfFile\""
}
},
"bodyPatterns": [ {
"matches": "PDF"
} ]
},
{
"headers": {
"Content-Disposition": {
"contains": "name=\"fileMetadataName\""
}
},
"bodyPatterns": [ {
"matches": "permissions,owner"
} ]
}
]
},
"response": {
"status": 201,
"jsonBody": {
"DocumentId": "123456789-123456789"
}
}
}
And here is an extract of the YAML that describes the multipart input:
paths:
'/files':
put:
tags:
- ProofOfConcept
summary: Upload a file in the files repository
description: Do the job
operationId: putFile
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- name: Source
description: ID of the sender
in: header
type: string
required: true
- name: theFile
description: The file to be uploaded
in: formData
required: true
type: file
- name: typeOfFile
description: 'File type: PDF, JPG...'
in: formData
required: true
type: string
- name: fileMetadataName
description: 'Metadata name. Possible values are: permissions, owner, group, creationDate, appGeneratedId (format: <app-name>;<id>)'
in: formData
type: array
items:
type: string
- name: fileMetadataValue
description: Value associated to the corresponding metadata name
in: formData
type: array
items:
type: string
responses:
'201':
description: Created
schema:
$ref: '#/definitions/DocumentId'
I expect to be able to match for fileMetadataName, for example, all permutations of :
permissions, owner, group, creationDate, appGeneratedId
And in the case of fileMetadataValue, I expect to be able to match regex values for all permutations (e.g. ([0-9]{3,3}) for permissions).

Limit access to Google Endpoint URL

I am trying to build a service to service API call. I am using Google Endpoints with open API.
My problem is that after adding "securityDefinitions:" I'm still able to access the endpoint without authentication. (Able to access it from anywhere)
How do I make sure that only Compute Engine with a particular Service Account can access the REST API.
swagger: "2.0"
info:
description: "A simple Google Cloud Endpoints API example."
title: "Endpoints Example"
version: "1.0.0"
host: "echo-api.endpoints.projectid.cloud.goog"
x-google-endpoints:
- name: "echo-api.endpoints.projectid.cloud.goog"
target: "SOME IP"
# [END swagger]
basePath: "/"
consumes:
- "application/json"
produces:
- "application/json"
schemes:
- "http"
paths:
"/list":
get:
description: "list"
operationId: "Project.get"
produces:
- "application/json"
responses:
200:
description: "lists"
schema:
$ref: "#/definitions/Project"
parameters:
- description: "Project Name"
in: body
name: project_id
required: true
schema:
$ref: "#/definitions/Res"
security:
- google_jwt_client-1: []
definitions:
Res:
properties:
apierrmsg:
type: "string"
apiresults:
type: "Array"
definitions:
Project:
properties:
project_id:
type: "string"
securityDefinitions:
google_jwt_client-1:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "some#projectid.iam.gserviceaccount.com"
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/some#projectid.iam.gserviceaccount.com"

Find list of collections by tags filter "OR"

I want make a filter tag system with mongoose.
The principle is simple, I have a model that has an array of string and an array in input.
I want select elements which contains tags in the input array.
Example:
game_console [{
name: "Playsation",
tags: ["old", "sony"]
}, {
name: "xBox",
tags: ["nintendo", "powerfull"]
}, {
name: "megadrive",
tags: ["old", "sega"]
}, {
name: "Gameboy",
tags: ["prehistory", "sega"]
}];
If I put in array input ["old", "sega"], I must get the elements: Playstation and Megadrive.
After searching I found $in and I tested that:
Preambule.find({
'tags': {
$in: tags_array_input
}
}).sort('-commentaires_size')
.exec(function(err, things) {
// [...]
});
It works but only if my field tags was not an array of String..
I don't know what to search in documentation.
My model :
var PreambuleSchema = new Schema({
titre: String,
description: String,
content: String,
auteur: String,
tags: [String],
votes: [],
commentaires: [{
"authorMail": String,
"content": String
}],
commentaires_size: Number,
date: String
});
I'm using yeoman fullstacks, Angularjs, mangoose, nodeJs.

Resources