How to properly document text/csv responses on swagger/yaml docs? - csv

I have a bunch of API endpoints that return text/csv content in their responses. How do I document this? Here is what I currently have:
/my_endpoint:
get:
description: Returns CSV content
parameters:
- $ref: '#/components/parameters/myParemeters'
responses:
200:
headers:
$ref: '#/components/headers/myHeaders'
content: text/csv
As it stands, this does not work and I get the note in the Swagger preview:
Could not render this component, see the console.
The question is how do I properly display the content for csv responses? I find if does work if I do add a schema, something like this:
...
content:
text/csv:
schema:
type: array
items:
type: string
...
But there shouldn't be a schema since it is csv. So to go back to the question, what is the proper way to describe the csv response content?

Your first example is not valid syntax. Replace with:
responses:
'200':
content:
text/csv: {} # <-----
# Also note the correct syntax for referencing response headers:
headers:
Http-Header-Name: # e.g. X-RateLimit-Remaining
$ref: '#/components/headers/myHeader'
components:
headers:
myHeader:
description: Description of this response header
schema:
type: string
As for your second example, OpenAPI Specification does not provide examples of CSV responses. So the schema could be type: string, or an array of strings, or an empty schema {} (this means "any value"), or something else. The actual supported syntax might be tool-dependent. Feel free to ask for clarifications in the OpenAPI Specification repository.

Here is another worked one for openapi 3.0.2 to return text/csv content (string) from backend:
Contract:
responses:
'200':
content:
text/csv:
schema:
type: string
Backend:
return ResponseEntity.ok("h1,h2,h3,h4\n1,2,3,4\n5,6,7,8");

Here is one more example:
Contract:
responses:
'200':
schema:
type: object
Backend:
return ResponseEntity.status(200).contentType(MediaType.parseMediaType("text/csv")).body("Col 1;Col2\naaa;bbb\nccc;ddd");

Related

Greasemonkey: POST data causes underscores in float numbers

let jsonString = JSON.stringify(json);
console.log(jsonString); //prints {"5667787":"currentTaxless":99.82,"current":123.78}}
GM.xmlHttpRequest({
method: "POST",
url: "https://exampleau.tld",
data: jsonString,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
onload: function(response) {
//stuff
}
});
Hi,
I am starting to feel myself stupid. I haven't found any way to feed into data regular object/array or json, no matter what I did (changed headers, added dataType, feed that json variable) - the data was not posted. Only this solution posts data. In the Greasemonkey documentation there is nothing about feeding plain json.
The problem is, that on backend, when I receive such a data - it is:
an array with single key and no value
the key is html_entity_encode(d) string
where dots in float numbers are replaced with underscores. This is what I am getting:
{"5667787":{"currentTaxless":99_82,"current":123_78}}
Qusetion: What am I doing wrong or how to post without a hassle or receive normally formatted posted data without a hassle using Greasemonkey???
Versions: Greasemonkey v4.11
Firefox v81
Nevermind.
The solution is not to
data: jsonString,,
but rather explicitly put json string under some key as value like this
data: 'data=' + jsonString,

Schema object properties validation

According to OpenAPI specification [https://swagger.io/specification/] I can define the minimum and maximum values of the field in the schema object properties.
But actually Google endpoint does not perform any validation
My Swagger file fragment:
parameters:
- name: message
in: body
description: sug
schema:
required:
- Message
properties:
Message:
type: integer
minimum: 1
maximum: 1
MessageId:
When I send a wrong request:
curl https://xxxxxxxxxxxxxxxxxxxxd"Message=10&MessageId=456789123456&TimeStamp=20190611101010212&OperatorId=15&GlobalAccountId=81165751216851320000&Reason=3"
The Endpoint does not reject the request, but invokes the cloud function.
You are correct. Google Cloud Endpoints doesn't do any OpenAPI object property validation.

JSON API property names and Swagger documentation for proper response modeling

I'm seeking the best way for documenting my rest API response according to JSON API and also how to describe it in Swagger YAML documentation.
My API receives a word and a list of URLs and returns how many times the given word appears in each website provided. My first take for the successful response was:
{
"data": {
"foo": {
"http://www.foobar.com": 12,
"http://www.bar.com": 0
}
}
}
Using the word and the URLs as property names.
I'd like to know if it is a good practice according to JSON API and if yes, how to document it in Swagger YAML:
swagger: '2.0'
info:
description: How many times a given word appears in each site provided? This API answer it
version: 1.0.0
title: WordApp
contact:
email: foo#bar.com
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
paths:
/:
get:
summary: returns how many times a given word appears in each provided URL
description: |
By passing in the appropriate options, you can search for
the number of occurrences of a given word in each URL provided
produces:
- application/json
parameters:
- in: query
name: word
description: pass a word for looking up its occurrences in each site
required: true
type: string
- in: query
name: url
description: a list of valid URLs
type: string
required: true
responses:
200:
description: search results matching criteria
schema:
type: array
items:
$ref: '#/definitions/Data'
500:
description: Internal Server Error
definitions:
Data:
type: object
required:
- word
- url
- value
properties:
word:
type: string
example: Brazil
url:
type: string
example: 'https://www.nytimes.com/'
value:
type: integer
example: 12
If it is not the best practice, what would be a better way of modeling my response?

Swagger / JSON — Optional fields being treated as required

I'm having some difficulty with Swagger 2.0 insiting that fields are required when they are not in fact defined to be required.
Here's a snipped version of my Swagger YML file.
definitions:
category:
type: object
required:
- name
- code
properties:
name:
type: string
description: Category name
code:
type: string
description: Category code
_links:
$ref: '#/definitions/categoryLinks'
children:
type: array
items:
$ref: '#/definitions/category'
categoryLinks:
required:
- self
- parent
- children
properties:
self:
description: Canonical link to this category
$ref: '#/definitions/genericLink'
parent:
description: Link to the parent category
$ref: '#/definitions/genericLink'
children:
description: Link to the child categories
$ref: '#/definitions/genericLink'
genericLink:
properties:
href:
type: string
description: The absolute URL being linked to.
paths:
'/categories/{category_code}':
get:
summary: Get a specific category
description: Returns information about a specific category.
parameters:
- name: category_code
description: Code of category to get
type: string
in: path
required: true
responses:
200:
description: Information about requested category.
schema:
$ref: '#/definitions/category'
The response from get '/categories/awesome-cat' looks like:
{
"name" => "My awesome Category",
"code" => "awesome-cat",
"_links" => {
"self" => {
"href" => "https://api.test.testing/categories/awesome-cat.json"
},
"parent"=> {},
"children" => {}
}
}
Which is as expected, and which conforms to my definiton of a category above.
I'm using the swagger rspec matcher called conform_to_the_documented_model_for provided by the Apivore project to validate the output from all my API endpoints:
matcher :conform_to_the_documented_model_for do |swagger, fragment|
match do |body|
body = JSON.parse(body)
#errors = JSON::Validator.fully_validate(swagger, body, fragment: fragment)
#errors.empty?
end
failure_message do |body|
#errors.map { |e| e.sub("'#", "'#{path}#").gsub(/^The property|in schema.*$/,'') }.join("\n")
end
end
Alas my test is failing.
3) the V1 API path /categories/{category_code} method get response 200 responds with the specified models
Failure/Error: expect(response.body).to conform_to_the_documented_model_for(swagger, fragment)
'#/_links/parent' did not contain a required property of 'href'
'#/_links/children' did not contain a required property of 'href'
'#' did not contain a required property of 'children'
For some reason the JSON validator is not regarding the href property of the link as optional, nor is it regarding rhe children property of category as optional.
It was my understanding that properties not listed under the required section are optional. Why is the JSON::Validator.fully_validate regarding them as non-optional?
Dave, just answering here too for completeness. The latest version of the Apivore gem, 0.0.2, no longer uses the :strict mode of the JSON Validator gem json-schema, which makes the assumption that all fields are required. This is a recent change I made after we sorted out the misunderstandings around additionalProperties. I am now of the opinion that the :strict mode of the validator isn't very helpful. The default JSON schema validation is correct, there is no reason to be any 'stricter'.
Making sure you have the latest version of the Apivore gem (0.0.2, or greater) should solve your problem.

Swagger UI 2.1 Stuck "fetching resource list"

I have a RESTful API that I have created recently and I won't remember how to use it in a few months. I decided to document my API using Swagger, however I'm going crazy.
I used http://editor.swagger.io/ to create the YAML file that I then convert into a JSON file Swagger can use. When I put file into Swagger UI it just gets stuck at fetching resource list: localhost/swagger.json and the console says Uncaught TypeError: Cannot read property '$ref' of undefined .
I'm using version 2.1.0-alpha.5 of Swagger UI.
Here is my spec file:
swagger: '2.0'
info:
title: TITLE
description: BLAH, BLAH, BLAH, ETC
version: "1.0b"
host: api.example.com
schemes:
- http
basePath: /v1
produces:
- application/json
paths:
/match.json:
get:
#summary: Match Data
description: Used for getting data about a match
parameters:
- name: id
in: query
description: The match ID of from a game
required: true
type: integer
format: int32
- name: key
in: query
description: API key used for authentication.
required: true
type: string
responses:
200:
description: Returns match data
schema:
type: array
items:
$ref: '#/definitions/MatchData'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
definitions:
MatchData:
properties:
info:
type: integer
format: int64
description: General information about the match
time:
type: integer
format: int64
description: Information about the start/end time
stats:
type: array
format: int64
description: Stats about the match
Error:
required:
- errorID
- message
properties:
errorID:
type: string
description: Error ID.
message:
type: string
description: Information about the error.
I've tested your spec, and while I'm not getting the same error you do, the spec is indeed invalid.
If you look at #/definitions/MatchData/properties/stats, you'll see that you define the type: array but you don't provide an 'items' property next to it to say which array it is (and that's mandatory). You may have intended to use type: integer like the properties above it, which goes along with the format: int64.
Since I don't know what you intended to provide, it's difficult to give an accurate solution, but if you add a comment with what you intended to do, I could provide a more detailed answer.
Upon some additional testing, I discovered that there's a bug in the UI. After you make that modification and the spec loads, the operation itself will not expand unless you click on the Expand Operations link. I've opened an issue about it, feel free to follow it there.
This problem can be due to some indentation errors in the yaml file which actually did not show up in the Swagger editor. Check all your definitions and whether they are getting displayed as expected in the preview that you can see in Swagger editor (especially check MatchData).
You can also try giving:
responses:
200:
description: Returns match data
schema:
type: array
items:
schema:
$ref: '#/definitions/MatchData'
For our case, we used Swagger-php and we have:
* #SWG\Response(
* response=200,
* description="app response"
* #SWG\Schema(
* type="array"
* )
* ),
but we missed " * #SWG\Items(ref="#/definitions/pet")". After removing "#SWG\Schema(", it works e.g.
* #SWG\Response(
* response=200,
* description="app response"
* ),