Request body does not show up in curl example with OpenApi3 + widdershins + shins - api

I am generating API documentation for our Java endpoints. I am using widdershins to convert our openAPI3.0 yaml file to markdown. Then, I am using shins to convert the markdown file to html. The request body for all of our endpoints does not appear in the generated cURL examples. Why is this? This defeats the purpose of having cURL examples because copying and pasting a cURL example without the required body will not work. Can anyone recommend a workaround or alternative tool that generates good documentation with complete cURL examples?
Example endpoint from our openAPI.yaml file...
post:
tags:
- Tools
description: Installs a tool on a user's account
operationId: Install Tool
requestBody:
description: UserTool object that needs to be installed on the user's account
content:
application/json:
schema:
$ref: '#/components/schemas/UserTool'
required: true
parameters:
responses:
default:
description: default response
content:
application/json:
schema:
$ref: '#/components/schemas/Message'
This is the documentation our toolchain generates from this yaml file...
We would like to add a line just like the one below (grey highlight) to our cURL examples. This is a chunk from the markdown file that Widdershins produces from our openAPI yaml file. I manually added the –“d
This stack overflow Q/A suggests the answer is it is impossible to include a body parameter in a code example using swagger or openAPI. Is this correct? If so, why is this the case? What's the reasoning?
Cheers,
Gideon

I also had the same problem.
As a result of trial and error, it was found that the behavior displayed on curl varies depending on the in value.
Please look at the ParameterIn enum.
public enum ParameterIn {
DEFAULT(""),
HEADER("header"),
QUERY("query"),
PATH("path"),
COOKIE("cookie");
I tried by like below at first time:
new Parameter().name("foo").in(ParameterIn.HEADER.name())
But name return like "HEADER", So swagger(or OpenAPI) recognized to header.
It should be lower character like "header" follow ParameterIn enum.
So, you can fix it like this
new Parameter().name("foo").in(ParameterIn.HEADER.toString())
or
new Parameter().name("foo").in("header")

I also encountered the same problem and I did a little digging. It turns out I had to set options.httpSnippet option in widdershins to true so that the requestBody params will show up. However, setting that to true just shows the params if content type is of application/json. For multipart-form-data, you need to set options.experimental to true as well.
Unfortunately, there is a bug in widdershins for handling application/x-www-form-urlencoded content-type.. I created a PR for it which you can probably manually patch on the widdershins package. PR link: https://github.com/Mermade/widdershins/pull/492/files

Related

Conditional OpenAPI request body when query param provided

I have the following endpoints configured for managing types of food
POST ~ /food/types
GET ~ /food/types
GET ~ /food/types/{id}
PUT ~ /food/types/{id}
Delete ~ /food/types/{id}
I'm trying to represent a clone operation in my REST API and wanted to avoid the use of Verbs in my endpoints.
After some research I've come up with the following as it conforms the most out of other solutions i could think of to basic REST principles:
POST ~ /food/types?sourceId={id}
This would mean that the method for this endpoint (in a typical MVC framework) would need to conditionally handle both the creation when a JSON payload is sent, and the duplication of a resource when a query parameter is provided.
I'm trying to think how i can express that in my OpenAPI specification document (v3.0.2)
Here is what i've got so far:
/api/food/types:
post:
summary: Create a new type of food
responses:
'201':
description: Created
content:
application/json:
schema:
$ref: ./response/food-type.yaml
'400':
description: Bad Request
requestBody:
content:
application/json:
schema:
$ref: ./request/food-type.yaml
description: Create a new type of food
tags:
- Food Type
parameters: []
The request/food-type.yaml contains an object with two required parameters:
Name,
Category
When my framework validates the request against the OpenAPI specification, i want it to sometimes ignore the request body if and only if, a request parameter has been provided with a 'sourceId' parameter.
Is this type of thing even possible to express in OpenAPI 3+, or am i going about this the wrong way?
Simply put, is it possible to ignore the request body when a specific query parameter has been provided in a post request using OpenAPI 3.
And following that question, is my approach to REST lacking, and is there a better way i could represent the cloning of a resource in my API?
Use the body of the message instead to describe the source:
POST /food/types {"clone": "{id}"}
You can even use verb if you convert them into nouns:
POST /food/type-cloning {"source": "{id}"}

Adding a note to Request sample in OpenAPI

Is it possible to add a note to the field where the Request Samples show on Swagger UI?
My API is described in the following way:
/v1/test:
post:
summary:test
tags:
- test
description: test
parameters:
- in: body
name: body
required: false
schema:
$ref: '#/definitions/test'
x-code-samples:
- lang: cURL
source: >-
When the yaml is rendered by our UI program, the Request sample is shown like this:
sample request
Is it possible to add a note someplace marked in red on the image?
I have tried adding x-description and x-summary, but that doesn't work.
I wonder if this is possible at all.
Thank you

When I import Swagger API to Postman, all request names end up blank in Postman GUI

I am QA engineer. The Dev team produces documentation for our product's RESTful API using Swagger. I need to import this to Postman to make it easy to invoke the product's API.
After importing the JSON file (in Swagger format) into Postman, there is 1 but big problem: All titles (and descriptions) of individual requests are blank! (see screen shot below).
Apparently, this is a known issue, documented here: https://github.com/postmanlabs/postman-app-support/issues/1434
We have literally hundreds of requests. I need to find a sufficiently effective yet simple way to ensure all request titles in Postman are populated with a value which I would like to calculate on the fly.
I have been considering the following approach:
Write a command line tool (using NodeJS or another
solid platform) which will receive:
1. ID of the collection to fix
2. api key
It will iterate through all requests in the
collection. For each request: if Name field is
blank, then a substring of the request URL
will be assigned to the Name field; if name is
not blank, the request is left alone.
What I am unsure about:
Can I do this programmatically from Postman? It does not make sense to put this code into any one individual request (as pre or post).
(If I have to code this util outside of Postman)
For NodeJS there are "postman-collection" and
"postman-sdk" but I am slightly confused which I
should use.
Unfortunately, I have not yet found any suitable > library for maintaining Postman collections using C# > or Java.
I am quite frankly confused by the available options. Any guidance will be appreciated.
I had the same problem, solved it thanks to Ian T Price solution (just copy operationId value into a new key summary). I decided to write a little javascript utility for this:
function swagPostman(swaggerJson) {
for (let path in swaggerJson.paths) {
let methods = ["get", "head", "post", "put", "delete", "connect", "options", "trace", "patch"];
methods.map(method => {
if ((swaggerJson.paths[path] || {})[method]) {
swaggerJson.paths[path][method].summary =
swaggerJson.paths[path][method].operationId;
}
});
}
return JSON.stringify(swaggerJson);
}
Also made a simple pen where to run the script with a GUI: https://codepen.io/0x616c65/full/pMaQpb. You just copy-paste your swagger.json file in that pen and woilà!
A simple answer to this is to add a line summary: <RequestName>
I came across this problem using the excellent APIs-Gurus OpenAPIDirectory repo
These swagger.yaml files have a operationId: line which can be duplicated and the key replaced with summary: using:
awk '{if (!/ operationId:/) {print ; next} ; { print; a=gensub(/ operationId:/, " summary:",1) ; print a}}' swagger.yaml > swagger-new.yaml
Importing this into Postman then shows the correct request name.
PostMan is separating out the Import/Export functions in to separate plug-ins but their plug-in model leaves a lot to be desired at the current time.

Onenote API (REST) - PATCH append - "must include a 'commands'" error when Commands is already supplied (?!)

Note: I'm pretty sure nothing's wrong with the PATCH query, I had it working before with 'Content-type':'application/json' and a constructed json file:
[
{
'target':'|TARGET_ID|',
'action':'append',
'content':'|HTML|'
}
]
For the purposes of this, the header supplied (authentication bearer is correct and will be omitted)
'Content-type':'multipart/form-data; Boundary=sectionboundary'
(note: Boundary=sectionboundary is in the same line)
Attempting to pass the following body as a PATCH to
https://www.onenote.com/api/v1.0/pages/|GUID|/content
returns a
"code":"20124","message":"A multi-part PATCH request must include a 'commands' part containing the PATCH action JSON structure." :
--sectionboundary
Content-Disposition: form-data; name="Commands"
Content-Type: application/json
[
{
'target':'|TARGET_ID|',
'action':'append',
'content':'|HTML|'
}
]
--sectionboundary
Content-Disposition: form-data; name="image-part-name"
Content-Type: image/png
|BINARY_IMAGE_DATA|
--sectionboundary--
As you can see, there's a Commands section already. Using smallcaps 'commands' doesn't help, and the correct syntax should be "Commands" as per the OneNote Dev Center documentation.
PS: |TARGET_ID| |HTML| |GUID| and |BINARY_DATA| are replaced with the correct content at runtime. Due to privacy constraints, the fact that you may use a different schema than I do, and how long |BINARY_IMAGE_DATA| actually is, I will not show the actual input unless required to solve the problem.
Would like to know if I missed anything - thanks in advance.
PPS: Yes, I realize i've omitted the img tag inside |HTML| somewhere. It shouldn't have anything to do with code 20124, and if I got it wrong should return another thing entirely.
Based on investigating the request information you shared, I can confirm that the PATCH request referenced as part of the correlation you provided does not match your posted header information.
The correlated PATCH request shows up as a multi-part request with only a single part that has Media Type "TEXT/HTML" and not "Application/JSON". Can you please check and confirm your request content ?
Let us continue to discuss this on email. If you still face issues calling the API, please write to me at machandw#microsoft.com
Regards,
Manoj

How to retrieve a list of all articles of Fogbugz-wiki that have a certain tag?

Via the Fogbugz REST API I try to get all articles with a certain tag. I wrote some code in python to get it but I got "zero" as result. Here is my code:
import requests
...
some code to log in
...
req_params={"cmd": "search", "token": self.token,"q":"tag:\"my_cool_tag\""}
response = requests.get(req_url, data=req_body, headers=req_header, params=req_params, verify=False)
print (response.text)
as response I got:
...cases count="0"...
Is there a way to get all articles with a certain tag in a list via REST-API and how I can achieve this?
I am using FogBugz Version 8.8.49.0.
Try the search with curl or directly in your web browser to check that it works, then see if you can debug your Python.
In a browser I can successfully query FogBugz Online with something like:
https://<domain>.fogbugz.com/api.asp?token=<token>&cmd=search&q=tag:%22<my_tag>%22
Although I entered quotes around my tag, the browser url encoded them to %22. Obviously <domain>, <token> and <my_tag> should be replaced with your own values.
Your basic parameters look OK, but I haven't used Python so am not sure whether escaping the quotes around the tag translates well to the GET request? Maybe try url encoding "my_cool_tag".