Our current deployment patterns require me to manually write my swagger json output that will be consumed by the Swagger-based UI in use at my company. I'd like the json I'm writing to provide 'default' values to populate the Swagger UI for all input fields, including the body input parameter. My body parameter is a referenced object as seen below. How do I define the returned swagger JSON to auto populate the body portion of the request when the "Try this operation" is clicked?
An example Swagger spec that has no default/example data populated in the Swagger UI is below.
{
"swagger":"2.0",
"info":{
"description":"Example API Description",
"title":"Example Title",
"version":"v3.0"
},
"tags":[
{
"name":"v3"
}
],
"consumes":[
"application/json"
],
"produces":[
"application/json"
],
"paths":{
"/v3/api/{subscriptionID}/example":{
"post":{
"tags":[
"v3"
],
"description":"This API will do something",
"consumes":[
"application/json"
],
"produces":[
"application/json"
],
"parameters":[
{
"name":"Accept",
"in":"header",
"description":"The Accept request-header field can be used to specify the media types which are acceptable for the response. If not provided, the default value will be application/json",
"required":false,
"default":"application/json",
"type":"string"
},
{
"name":"Content-Type",
"in":"header",
"description":"The MIME type of the body of the request. Required for PUT, POST, and PATCH, where a request body is expected to be provided.",
"required":true,
"default":"application/json; charset=utf-8",
"type":"string"
},
{
"name":"company_locale",
"in":"header",
"description":"The desired language as spoken in a particular region preference of the customer of this particular transaction. Consists of two lower case language",
"required":true,
"default":"en_US",
"type":"string"
},
{
"name":"originatingip",
"in":"header",
"description":"The originating ip address of the calling device or browser.",
"required":true,
"default":"100.100.10.1",
"type":"string"
},
{
"name":"transaction_id",
"in":"header",
"description":"The transaction identifier for this invocation of the service. ",
"required":true,
"default":"1e2bd51d-a865-4d37-9ac9-c345dc59119b",
"type":"string"
},
{
"name":"subscriptionID",
"in":"path",
"description":"The unique identifier that represents the subscribed portfolio of products.",
"required":true,
"default":"1e2bd51d",
"type":"string"
},
{
"name":"body",
"in":"body",
"description":"The body of the request",
"required":true,
"schema":{
"$ref":"#/definitions/exampleDefinition"
}
}
],
"responses":{
"200":{
"description":"OK",
"headers":{
"transaction_id":{
"type":"string",
"default":"de305d54-75b4-431b-adb2-eb6b9e546013",
"description":"The identifier for the service transaction attempt."
}
}
}
}
}
}
},
"definitions":{
"exampleDefinition":{
"type":"object",
"description":"Request details for Example Definition",
"properties":{
"action":{
"type":"string",
"description":"Specifies the action to be taken"
},
"applyToBase":{
"type":"string",
"description":"A boolean value that defines the behaviour of the request against the base"
},
"addOnIDs":{
"type":"string",
"description":"The identifiers for the add-ons"
}
},
"required":[
"action",
"applyToBase",
"addOnIDs"
]
}
}
}
I have been testing this json at http://editor.swagger.io/#/ by clicking File->Paste JSON.... I then click "Try this operation", scroll down and observe that the values of my body parameter are not populated - that's what I'd like to change.
Thanks in advance for any suggestions.
To have example values, you just have to add an "example" property where needed:
exampleDefinition:
type: object
description: Request details for Example Definition
properties:
action:
type: string
description: Specifies the action to be taken
example: An action value
applyToBase:
type: string
description: >-
A boolean value that defines the behaviour of the request against the base
example: An apply to base value
addOnIDs:
type: string
description: The identifiers for the add-ons
example: an ID
Unfortunately the online editor don't propose them but SwaggerUI does:
To populate default values to be used when clicking on the "Try this operation" you just need to add the 'default' parameter for the properties in the definition. This works in the online editor:
{
"swagger":"2.0",
"info":{
"description":"Example API Description",
"title":"Example Title",
"version":"v3.0"
},
"tags":[
{
"name":"v3"
}
],
"consumes":[
"application/json"
],
"produces":[
"application/json"
],
"paths":{
"/v3/api/{subscriptionID}/example":{
"post":{
"tags":[
"v3"
],
"description":"This API will do something",
"consumes":[
"application/json"
],
"produces":[
"application/json"
],
"parameters":[
{
"name":"Accept",
"in":"header",
"description":"The Accept request-header field can be used to specify the media types which are acceptable for the response. If not provided, the default value will be application/json",
"required":false,
"default":"application/json",
"type":"string"
},
{
"name":"Content-Type",
"in":"header",
"description":"The MIME type of the body of the request. Required for PUT, POST, and PATCH, where a request body is expected to be provided.",
"required":true,
"default":"application/json; charset=utf-8",
"type":"string"
},
{
"name":"company_locale",
"in":"header",
"description":"The desired language as spoken in a particular region preference of the customer of this particular transaction. Consists of two lower case language",
"required":true,
"default":"en_US",
"type":"string"
},
{
"name":"originatingip",
"in":"header",
"description":"The originating ip address of the calling device or browser.",
"required":true,
"default":"100.100.10.1",
"type":"string"
},
{
"name":"transaction_id",
"in":"header",
"description":"The transaction identifier for this invocation of the service. ",
"required":true,
"default":"1e2bd51d-a865-4d37-9ac9-c345dc59119b",
"type":"string"
},
{
"name":"subscriptionID",
"in":"path",
"description":"The unique identifier that represents the subscribed portfolio of products.",
"required":true,
"default":"1e2bd51d",
"type":"string"
},
{
"name":"body",
"in":"body",
"description":"The body of the request",
"required":true,
"schema":{
"$ref":"#/definitions/exampleDefinition"
}
}
],
"responses":{
"200":{
"description":"OK",
"headers":{
"transaction_id":{
"type":"string",
"default":"de305d54-75b4-431b-adb2-eb6b9e546013",
"description":"The identifier for the service transaction attempt."
}
}
}
}
}
}
},
"definitions":{
"exampleDefinition":{
"type":"object",
"description":"Request details for Example Definition",
"properties":{
"action":{
"type":"string",
"description":"Specifies the action to be taken",
"default": "The default Action"
},
"applyToBase":{
"type":"string",
"description":"A boolean value that defines the behaviour of the request against the base",
"default": "0"
},
"addOnIDs":{
"type":"string",
"description":"The identifiers for the add-ons",
"default": "The default Add-On"
}
},
"required":[
"action",
"applyToBase",
"addOnIDs"
]
}
}
}
```
Related
I'm using go-restful in combination with go-restful-openapi to generate my swagger doc automatically. However, on testing the tool with the swagger-editor, I get the following error:
$refs must reference a valid location in the document
struct
type Users struct {
# uuid imported from github.com/google/uuid#v1.2.0
RelatedUsers []uuid.UUID `json:"relatedIds" validate:"required"`
}
generated swagger snippet
"Users": {
"required": [
"relatedIds"
],
"properties": {
"relatedIds": {
"type": "array",
"$ref": "#/definitions/uuid.UUID" #this line returns an error
}
}
}
}
Here's the swagger config:
swaggerConfig := restfulspec.Config{
WebServices: restfulContainer.RegisteredWebServices(),
APIPath: "/swagger.json",
PostBuildSwaggerObjectHandler: func(swo *spec.Swagger) {
swo.Info = &spec.Info{
InfoProps: spec.InfoProps{
Title: "User Service",
Description: "An example service for stackoverflow",
Version: "1.0.0",
},
}
},
}
NOTE: If I replace the lines above in the swagger editor as follows the error disappears, however, I couldn't figure out how to configure swagger to do so automatically
"Users": {
"required": [
"relatedIds"
],
"properties": {
"relatedUsers": {
type: array
items:
type: "string"
format: "uuid"
}
}
}
}
Just in case someone is running into this issue: go-restful-openapi cannot resolve imported custom types. To solve this issue add the type to the definitions
swo.Definitions["uuid.UUID"] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "uuid",
},
}
I want to add token endpoint oauth/token into my API documentation so I configured Docket like this:
public Docket api(UserProperties userProperties) {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/error")))
.paths(Predicates.not(PathSelectors.regex("/oauth/authorize")))
.paths(Predicates.not(PathSelectors.regex("/oauth/check_token")))
.paths(Predicates.not(PathSelectors.regex("/oauth/token_key")))
.paths(Predicates.not(PathSelectors.regex("/oauth/confirm_access")))
.paths(Predicates.not(PathSelectors.regex("/oauth/error")))
.build().apiInfo(apiInfo());
}
swagger-ui display page correctly, however 3rd party validator claims that:
Swagger schema validation failed.
Data does not match any schemas from 'oneOf' at #/paths//oauth/token/post/parameters/1
Data does not match any schemas from 'oneOf' at #/paths//oauth/token/post/parameters/1
Missing required property: schema at #/
Missing required property: type at #/
Missing required property: $ref at #/paths//oauth/token/post/parameters/1
JSON_OBJECT_VALIDATION_FAILED
The swagger.json taken from /api/v2/api-docs:
"/oauth/token": {
"get": {
...
},
"post": {
"tags": [
"token-endpoint"
],
"summary": "postAccessToken",
"operationId": "postAccessTokenUsingPOST",
"consumes": [
"application/json"
],
"produces": [
"*/*"
],
"parameters": [
{
"name": "name",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "parameters",
"in": "query",
"description": "parameters",
"required": true,
"items": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
],
"responses": {
...
},
"deprecated": false
}
},
Why springfox generates invalid schema?
So far I'm able to do swagger validation if the parameters are from "in": "body" or if the input expected is in a json format.
However, I can't find how to validate a simple string entered as formData.
Below is my swagger script (in json format)
v1swag = {
"cancels_post": {
"tags": ["/api/v1"],
"parameters": [
{
"name": "token",
"in": "formData",
"type": "string",
"required": True,
"description": "Cancels the provided token.",
}
],
"responses": {
"200": {
"description": "Success!",
}
}
}
}
I removed the schema as it seems to only work for "in": "body"
I've been searching the net but can't seem to find the light.
Though I will still be searching... Any hints would be greatly appreciated.
Thank you very much in advance.
A different source media type has to be consumed here. Specify "consumes" member to include media type of application/x-www-form-urlencoded.
v1swag = {
"cancels_post": {
"tags": ["/api/v1"],
"consumes": [
"application/x-www-form-urlencoded"
],
"parameters": [
{
"name": "token",
"in": "formData",
"type": "string",
"required": True,
"description": "Cancels the provided token.",
}
],
"responses": {
"200": {
"description": "Success!",
}
}
}
}
I am returning a Uri as the location header of the response from my web-api controller, as shown below:
[HttpPost]
public HttpResponseMessage PostTenant([FromBody] JObject value)
{
string tenantName;
try
{
tenantName = value.GetValue("name").ToString();
}
catch (Exception e)
{
throw new HttpResponseException(
this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, e));
}
try
{
DbInteract.InsertTenant(tenantName.Replace(" ", string.Empty));
var uri = Url.Link("TenantHttpRoute2", new { tenantName });
var response = new HttpResponseMessage(HttpStatusCode.Created);
response.Headers.Location = new Uri(uri);
return response;
}
catch...
}
The swagger-ui client makes the POST request, but the response headers don't contain the Location uri. It appears like this:
POST request from Swagger-ui
As you can see in the image, the RESPONSE HEADERS are
{
"content-type": null
}
The swagger JSON for this post request is:
"post": {
"tags": [
"Tenant"
],
"summary": "Add a new tenant",
"description": "Adds a tenant and returns admin user account information to be used in further calls.",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "Tenant",
"description": "Name of the tenant must be alphanumeric without any special characters.",
"required": true,
"schema": {
"$ref": "#/definitions/CreateTenant"
}
}
],
"responses": {
"201": {
"description": "Tenant Inserted",
"headers": [
{
"description": "Location",
"type": "string"
}
]
},
"400": {
"description": "Invalid JSON Format of input"
},
"405": {
"description": "Tenant by this name already exists; Use PUT instead"
},
"500": {
"description": "InternalServerError"
}
}
}
What's wrong here? Why can't I see the response header in swagger-ui? Please let me know if you need more information. Thanks
The intent seems clear enough: a successful response returns a 201 Created with a Location header pointing at the newly created resource. Should work ...
I might remove the "produces" attribute, since you haven't defined any response anywhere.
Try with:
"headers" : { "Location" : { "description": "...", "type" : "string" } }
Instead of:
"headers" : []
so object instead of arrays.
I want to POST below JSON string as part of request body in I/O DOC.
{"Name":"ABCD","Alias":"PS","Date":"20140604","Status":"New","PdfPath":"/folder1/app.pdf"}
What will be the configuration of endpoint?
I am using below endpoint configuration, but it is not working.
{
"endpoints": [
{
"name": "Information",
"methods": [
{
"MethodName":"Add Product",
"Synopsis": "Used to add Product for TEST purpose. This service is called internally, hence this helppage serves as a mockup for the internal call",
"HTTPMethod":"POST",
"URI":"/ServiceHost/test.svc/add-testService",
"RequiresOAuth":"N",
"parameters":[
{
"Name":"Name",
"Default":"A",
"Type":"enumerated",
"EnumeratedList": ["A","B","C"],
"DefaultValue":"N/A",
"IsMandatory":"Yes",
"Description":"This refers to the name."
},
{
"Name":"Alias",
"Default":"AB",
"Type":"string",
"DefaultValue":"N/A",
"IsMandatory":"Yes",
"Description":"This refers to the code."
},
{
"Name":"Date",
"Default":"",
"Type":"string",
"DefaultValue":"N/A",
"IsMandatory":"Yes",
"Description":"This refers to the date."
},
{
"Name":"Status",
"Default":"",
"Type":"string",
"DefaultValue":"New",
"IsMandatory":"No",
"Description":"This refers to the status."
},
{
"Name":"PdfPath",
"Default":"",
"Type":"string",
"DefaultValue":"Empty String",
"IsMandatory":"No",
"Description":"This refers to the full pdf path."
}
]
}
]
}
]
}
You need to use Type as textarea. This would create request body where you can post your inputs. To be more specific you could mention the type of the input that you would POST using content-type parameter.
"contentType": "application/xml",
"type": "textarea",
I think this would solve ur problem