Changing $ref in Swashbuckle Swagger Generation for response object - asp.net-core

I'm producing a swagger for a simple api that returns an object which correctly generates the swagger response similar to the below. My question is, is it possible to change the definition from myCustomerMadeUpResponse to customerResponse.
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/myCustomerMadeUpResponse"

Related

Using $vars within json schema $ref is undefined

While following the documentation for using variables in json schema I noticed the following example fails. It looks like the number-type doesn't get stored as a variable and cannot be read.
{
"$id": "http://example.com/number#",
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["natural", "integer"]
},
"value": {
"$ref": "#/definitions/{+number-type}",
"$vars": {
"number-type": {"$ref": "1/type"}
}
}
},
"required": ["type", "value"],
"definitions": {
"natural": {
"type": "integer",
"minimum": 0
},
"integer": {
"type": "integer"
}
}
}
results in
Could not find a definition for #/definitions/{+number-type}
tl;dr $vars is not a JSON Schema keyword. It is an implementation specific extension.
The documentation you link to is not JSON Schema. It is documentation for a specific library which adds a preprocessing step to its JSON Schema processing model.
As such, this would only ever work when using that library, and would not create an interoperable or reuseable JSON Schema, if that's a consideration.
If you are using that library specifically, it sounds like a bug, and you should file an Issue in the appropriate repo. As you haven't provided any code, I can't tell what implementation you are using, so I can't be sure on that.

NSwag generated client still serializes string for text/plain body

UPDATE: I went ahead and created an issue on NSwag after looking through its code. You can see it here: https://github.com/RicoSuter/NSwag/issues/3824
I have a functioning api endpoint that accepts "text/plain" as the body. The user of this endpoint is a third-party that controls the content type so I can't change that. I'm using NSwag to generate a c# client based on a swagger.json.
My main problem is that the generated client's function for calling this endpoint still serializes the string body, which causes the endpoint to fail to parse. I'm not 100% certain if this is a bug in my swagger.json or if it's something unintentional, because the json is also generated. This is why I'm not posting this on the NSwag github issues currently.
Here's what the swagger.json looks like:
{
"openapi": "3.0.1",
"info": {
"title": "PlainTextParser",
"version": "1.0"
},
"paths": {
"/api/v1/text": {
"post": {
"tags": [
"TextEvent"
],
"summary": "Parses a plain text body",
"operationId": "PostTextEvent",
"requestBody": {
"description": "Accepts a plain text body",
"content": {
"text/plain": {
"schema": {
"type": "string",
"nullable": true
}
}
}
},
"responses": {
"202": {
"description": "Success"
}
}
}
}
},
"components": { }
}
When I run nswag on it, I get this inside of the generated client:
public virtual async System.Threading.Tasks.Task PostTextEventAsync(string body, System.Threading.CancellationToken cancellationToken)
{
//...
var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value));
content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("text/plain");
//...
}
The SerializeObject method call is what is causing the issue. When I removed it everything worked fine. You can even see on the second line there that it understands the content type, which is why I'm confused why it's trying to serialize it.
So is there something I'm missing in the swagger.json or is there a bug in NSwag?
I do realize I can work around this by making my API endpoint reformat the string to its intended state, but that feels like a hack.

API standard design - swagger parameter body VS URI

I would like to clarify what is the design standard to query a list of array.
json data:
"ids": [
{
"id": "bbbbeeee1111",
"type": "student"
},
{
"id": "bbbbeeee2222",
"type": "teacher"
}
],
GET endpoint
/api/testitem
swagger parameter body
{
"ids": ["bbbbeeee1111;student"]
}
swagger returned the URI like this , the %3B seems wrong. some coding issues at API design?
http://localhost:8888/api/testitem?ids=bbbbeeee1111%3Bstudent

Mulitpart forms and nested objects Insomnia REST client

So I've decided to switch to Insomnia from Postman, as for some reason my Postman app keeps hanging. Everything is going well but I'm having trouble using multipart forms with Insomnia. How would I access this in Insomnia? In Postman I just need to put profile{location} as the field and it works, but Insomnia gives me an error of can't read property '0' of undefined
The object is structured as follows
{
"id": "5e76dd60d49dfd6827688908",
"username": "TLCFan",
"email": "tlc#fan.com",
"profile": {
"avatar": {
"url": "/static/img/defaultAvatar.png"
},
"header": {
"url": "/static/img/defaultBG.png"
},
"forHire": false,
"location": "Bimingham",
"bio": "Design is my life, but this is my story"
}
}

How to setup Swashbuckle/swagger-ui to render an array of strings as comma-delimited and correctly quoted within a multipart/form-data request?

I am using ASP.NET Core 3.0 (<TargetFramework>netcoreapp3.0</TargetFramework>) and Swashbuckle 5.0.0-rc4 (<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />).
I have an API Controller Action Method which accepts an uploaded file (that is, an IFormFile) and some metadata and tags to associate with the POSTed file:
public async Task<IActionResult> Post(
string fileId = null,
IFormFile file = null,
[FromForm] IDictionary<string, object> metadata = null,
[FromForm] IEnumerable<string> tags = null)
{
// ...
}
I am able -- through sheer luck -- to get Swashbuckle/swagger-ui to send the metadata in a format that seems to be correct (except, I need to write something that will parse out the JSON from within the multipart/form-data fragment). The metadata parameter is OK.
I am having real problems with the tags parameter. The OpenAPI document generated by Swashbuckle is like this:
"/projects/{projectId}/features/imports": {
"post": {
"tags": [
"FeaturesImports"
],
"summary": "Import features from a file uploaded by the end user, or from a file already stored in XXX",
"parameters": [
{
"name": "fileId",
"in": "query",
"description": "The XXX File (Version) Id of the source file to import. Optional; if file is not provided, a fileIdmust be provided.",
"schema": {
"type": "string"
}
},
{
"name": "projectId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"format": "binary"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "object",
"additionalProperties": false
}
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"encoding": {
"file": {
"style": "form"
},
"metadata": {
"style": "form"
},
"tags": {
"style": "form"
}
}
}
}
},
To my eyes, the fact that we have:
"tags": {
"type": "array",
"items": {
"type": "string"
}
seems correct: I want to receive an array of strings.
However, when the swagger-ui renders the form, and the end user enters the required data, the submitted request is not as I would would expect. I would expect the tags data to be something like:
------WebKitFormBoundaryKQWA8MEJTEXgMvsj
Content-Disposition: form-data; name="metadata"
{
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
------WebKitFormBoundaryKQWA8MEJTEXgMvsj
Content-Disposition: form-data; name="tags"
["string1","string2",",","string4\""]
------WebKitFormBoundaryKQWA8MEJTEXgMvsj--
but what I end up getting is:
------WebKitFormBoundaryKQWA8MEJTEXgMvsj
Content-Disposition: form-data; name="metadata"
{
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
------WebKitFormBoundaryKQWA8MEJTEXgMvsj
Content-Disposition: form-data; name="tags"
string1,string2,,string4"
------WebKitFormBoundaryKQWA8MEJTEXgMvsj--
The problems with this are:
the when the data is bound to the Action Method's parameters, the IEnumerable<string> tags parameter only contains one string, and not the 4 I would expect
the individual strings are joined, using a comma; and any commas present in the "raw" strings are not escaped. It is therefore impossible to reconstruct the original intended data
Given the metadata parameter appears to be JSON encoded, I would expect the same for the tags parameter. However, the OpenAPI 3.0.2 spec says (at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#special-considerations-for-multipart-content) that,
If the property is complex, or an array of complex values, the default Content-Type is application/json
... so that explains the JSON encoding of the metadata parameter, and...
If the property is a primitive, or an array of primitive values, the default Content-Type is text/plain
... ah, and that explains the encoding of the tags parameter, since it is an array of primitive values.
I think the underlying problem is that swagger-ui does not yet support the "Encoding Object" that can be set for multipart parameters, but does anyone have any suggestions, tips, workarounds or other ideas that might be helpful here?