I am using Swashbuckle 5.6.0 and Swashbuckle.Examples.3.5.1 to document a WebApi2 project. I have an action which consumes an XML body and returns a text response. I want the documentation to include an example of the XML input - e.g. <SampleXml><!-- example XML --></SampleXml>.
My swagger output is below, except that for the purposes of this question I have added the content-type application/json to the comsumes property. In reality, I only want to allow application/xml and text/xml.
When I view this with Swagger, I see:
When parameter content type application/xml is selected, I get a generated XML example with my model name, i.e. <XmlModel></XmlModel>.
When parameter content type application/json is selected, I get my desired example input <SampleXml><!-- example XML --></SampleXml>.
How can I get the example input while parameter content type application/xml is selected?
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "Sample"
},
"host": "localhost:63434",
"schemes": [
"http"
],
"paths": {
"/sampleXml/": {
"post": {
"tags": [
"xmlSample"
],
"summary": "XML sample.",
"description": "Post XML sample",
"operationId": "Xml_Post",
"consumes": [
"application/xml",
"application/json",
"text/xml",
],
"produces": [
"text/plain"
],
"parameters": [
{
"name": "xmlContent",
"in": "body",
"description": "The content of the XML document.",
"required": true,
"schema": {
"$ref": "#/definitions/XmlModel"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
},
}
}
}
},
"definitions": {
"XmlModel": {
"type": "object",
"properties": {},
"example": "<SampleXml><!-- example XML --></SampleXml>"
}
}
}
To change the root XML tag from <XmlModel> to <SampleXml>, add xml.name to your schema definition:
"definitions": {
"XmlModel": {
"type": "object",
"xml": {
"name": "SampleXml"
}
}
}
This will produce the following sample XML in Swagger UI:
<?xml version="1.0" encoding="UTF-8"?>
<SampleXml>
</SampleXml>
And if you add property definitions:
"definitions": {
"XmlModel": {
"type": "object",
"xml": {
"name": "SampleXml"
},
"properties": {
"id": {
"type": "integer",
"example": 7,
"xml": {
"attribute": true
}
},
"foo": {
"type": "string",
"example": "bar"
}
}
}
}
your XML example will include the corresponding elements:
<?xml version="1.0" encoding="UTF-8"?>
<SampleXml id="7">
<foo>bar</foo>
</SampleXml>
However, if you want the literal string <SampleXml><!-- example XML --></SampleXml> containing a <!-- comment -->, it's not possible AFAIK.
Update: Swagger UI supports using literal XML strings only in response examples:
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
},
"examples": {
"application/xml": "<SampleXml><!-- example XML --></SampleXml>"
}
}
}
but not in request body examples.
Related
I'm using :
springdoc-openapi-ui : 1.6.6
springdoc-openapi-hateoas: 1.6.8
swagger-models: 2.1.12
spring-hateoas: 1.4.1
When i retrieve the generated openapi scheme from my rest services i get responses format for hateoas EntityModel withtout the content section. (v3/api-doc endpoint)
Is there a way to get the scheme generated with the content section ?
I get :
{
"EntityModelProject": {
"required": [
"name"
],
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"pattern": "[a-zA-Z0-9-_]*",
"type": "string"
},
"label": {
"type": "string"
},
"links": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}
I would like to have :
{
"EntityModelProject": {
"type": "object",
"properties": {
"content": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Project"
}
},
"links": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}
EDIT 1 :
After looking into spring-hateoas code i see that the EntitModel class contains the Jakson #JsonUnwrapped annotation on getContent method. In our project we use Gson and Nt jakson. With Gson serialization, the result containts de "content" section. Wtih jakson the content section is unwrap. I assume that, the scheme generated by springdoc-openapi interpret with jsackson and not gson.
EDIT 2 :
Indeed, the ModelResolver class of io.swagger.v3.core.jackson, read Jackson annotations to create schema. In my case, the #JsonUnwrapped annotation. Swagger schema generation seems to be not compatible with Gson formatted api.
I get the following error when creating API in Postman: "Invalid data type. Must be either, array, boolean, integer, number, object or string"
The error is fixed when converting the line "type": "file" to "type": "object", but I am not sure if there is a proper way for this situation. Because with this update, the request may not be passed when sending request in Postman.
"parameters": [
{
"in": "body",
"name": "file",
"description": "file",
"required": false,
"schema": {
"type": "array",
"items": {
"type": "file"
}
}
},
...
]
So, how can I fix the problem in Postman?
The problem is not with Postman, but with the API definition. "type": "file" is not a valid type value for use in schemas and body parameters, this type can only be used in in: formData parameters.
On the other hand, I do not add file while trying to test my app via Postman. For this reason, I just want to suppress the errors
In this case you could change "type": "file" to "type": "string" to suppress import errors. Or remove the entire problematic operation from the API definition.
How to properly define file uploads in OpenAPI
The API definition is trying to describe uploading of a file array - but this is not supported in OpenAPI 2.0 (swagger: '2.0'). OAS2 only supports upload of individual named files via multipart/form-data, in which case the API definition would look like this:
{
"swagger: "2.0",
...
"paths": {
"/something": {
"post": {
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "file1",
"type": "file" // A single file sent via form field "file1"
},
{
"in": "formData",
"name": "file2",
"type": "file" // Another file sent via form field "file2"
}
]
...
}
Uploading an array of files is supported in OpenAPI 3 though:
{
"openapi": "3.0.0",
...
"paths": {
"/something": {
"post": {
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "array",
"items": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
},
...
}
}
}
}
I'm trying to pass the spec parameter in the url to the swagger editor to be able to open the API spec passed in the URL
https://editor.swagger.io/?spec={...}
as documented here:
https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
spec SPEC Object={}. A JavaScript object describing the OpenAPI definition. When used, the url parameter will not be parsed. This is useful for testing manually-generated definitions without hosting them.
but it seems that doesn't work, here the example
below the spec put in the link:
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Swagger"
},
"paths": {
"/mypath": {
"get": {
"operationId": "listPets",
"parameters": [
{
"name": "limit",
"in": "query",
"required": false,
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "A paged array of pets"
}
}
}
}
}
}
I am creating an C# ASP.NET Core 2.0 REST API, all going well for the most part. It is using MVC routing to gen the REST API. The controllers are pretty simple.
// POST: api/Volume/{zoneID}/Set/{volume}
[HttpPost("{zoneId:int}/[action]/{volume:int}", Name = "Set")]
public IActionResult Set(int zoneId, int volume)
{
return CreateAndSend(strZonesLevel, zoneId, $"{volume:X2}");
}
Using the latest of everything, installed Swagger/Swashbuckle for AspNetCore 2.3.0 and the UI comes up with the APIs and all. The SwashBuckle UI works well, I can test the API etc.
The one exception is that on the UI, the Response type ALWAYS comes back as "Unknown Response Type."
https://i.stack.imgur.com/6qqBh.jpg
I have the following attributes in front of my class (all methods return the same type)
[Produces("application/json")]
[Route("api/Volume")]
[ProducesResponseType(typeof(ControllerResponseModel), 200)]
[ProducesResponseType(typeof(ControllerResponseModel), 400)]
[ProducesResponseType(typeof(ControllerResponseModel), 500)]
The generated JSON seems allright, the ControllerResponseModel is in the definition, and referenced in all the right places by the Volume API. Here is a subset.
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "AVController API"
},
"paths": {
"/api/Volume/{zoneId}/Set/{volume}": {
"post": {
"tags": ["Volume"],
"operationId": "ApiVolumeByZoneIdSetByVolumePost",
"consumes": [],
"produces": ["application/json"],
"parameters": [
{
"name": "zoneId",
"in": "path",
"required": true,
"type": "integer",
"format": "int32"
},
{
"name": "volume",
"in": "path",
"required": true,
"type": "integer",
"format": "int32"
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/ControllerResponseModel" }
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/ControllerResponseModel" }
}
},
"500": {
"description": "Server Error",
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/ControllerResponseModel" }
}
}
}
}
}
},
"definitions": {
"ControllerResponseModel": {
"type": "object",
"properties": {
"command": { "type": "string" },
"message": { "type": "string" },
"url": { "type": "string" }
}
}
}
}
Any ideas why the UI would not be showing the return type and value? I have tried numerous things, like using gets instead of posts as well as using the [SwaggerResponse] attributes, but the results are the same.
This has been identified as an Edge browser issue with Swashbuckle, not the code posted here. It is reproducible on many sites. Issue has posted on GitHub # https://github.com/swagger-api/swagger-ui/issues/4337
We are using swagger 2.0 to document our .Net Web API's which we are hosting in Azure behind Azure API Management. I am having troubles getting the documentation to detail the complex objects that are being posted as part of the body. Azure shows no details about the object at all leaving me to have to document them myself. Below is the json file that I imported into Azure API Management.
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Hotel Search",
"description": "The seodecnvewjkl"
},
"basePath": "/v1",
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/xml",
"application/json"
],
"schemes": [
"http",
"https"
],
"paths": {
"/hotels/search": {
"post": {
"operationId": "searchCommand",
"description": "Searches for hotels",
"parameters": [
{
"name": "hotelSearchRq",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/HotelSearchRq"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"schema": {
"title": "HotelSearchRs",
"$ref": "#/definitions/HotelSearchRs"
}
},
"400": {
"description": "Bad Request"
},
"404": {
"description": "Unauthorised"
}
}
},
"get": {
"operationId": "searchQuery",
"parameters": [
{
"name": "CorrelationId",
"in": "query",
"type": "string"
}
],
"responses": {
"200": {
"description": "Successful response"
}
}
}
}
},
"definitions": {
"StayDetail": {
"type": "object",
"properties": {
"NumberOfGuests": {
"type": "integer"
},
"CheckinDate": {
"type": "string",
"format": "date",
"description": "the date that the stay starts from"
}
}
},
"HotelSearchCriteria": {
"type": "object",
"properties": {
"MaximumResults": {
"type": "integer",
"format": "int64"
},
"StayDetails": {
"$ref": "#/definitions/StayDetail"
}
}
},
"HotelSearchRq": {
"type": "object",
"properties": {
"CustomerTransactionIdentifier": {
"type": "string",
"description": "The customers transaction identifier"
},
"search_criteria": {
"$ref": "#/definitions/HotelSearchCriteria"
}
}
},
"HotelSearchRs": {
"type": "object"
}
}
}
Azure Api Management operation screen
Can someone please help me with how I can get the body documented automatically from the swagger documentation?
Currently the request and response body information from a Swagger doc are not displayed in the developer portal documentation.
This is no longer the case. Samples and schema are displayed in the developer portal.