Swagger: Add description with ref - swagger

I want to add a description to an object property that his definition is referenced. Something like that:
newCreditCard:
type: object
properties:
billingPhone:
description: Phone number of the card holder
$ref: "#/definitions/PhoneNumber"
But the editor warns that the description property will be skipped:
Extra JSON Reference properties will be ignored: description
I have found a less elegant workaround that works for the editor, but not for the Swagger UI (not sure that is may due to the recent update to 3.0.2 version of the Swagger UI)
newCreditCard:
type: object
properties:
billingPhone:
description: Phone number of the card holder
allOf:
- $ref: "#/definitions/PhoneNumber"
How do you do it in your Swaggers specification?
Thanks for the help!

If you add anything to the same level of $ref it will be ignored .
json $ref definition https://datatracker.ietf.org/doc/html/draft-pbryan-zyp-json-ref-03#section-3
correct way is to provide the description in the referenced object.

You could simply move the description property to the definition of PhoneNumber. Your original post does not show how you have defined PhoneNumber, but this snippet validates without warnings:
definitions:
phoneNumber:
type: string
description: Phone number of the card holder
newCreditCard:
type: object
properties:
billingPhone:
$ref: "#/definitions/phoneNumber"
If this answer is not what you are looking for, please restate the question. We need to know what you are trying to accomplish.

although it is not according to JSON standards.
if you are using Swashbuckle to generate your swagger.
i took advantage over the "Extensions" property of schema.
and managed to create a swagger JSON, with $ref and extended properties.
var refSchema = new OpenApiSchema
{
//Reference = new OpenApiReference { ExternalResource = referenceLink, Type = ReferenceType.Link }, this wont work and omit all your other properties
Extensions = new Dictionary<string, IOpenApiExtension>
{
{ "$ref" , new OpenApiString(referenceLink) } // adding ref as extension cause according to JSON standards $ref shouldnt have any other properties
},
Description = prop.Value.Description,
ReadOnly = prop.Value.ReadOnly,
Required = prop.Value.Required,
Type = prop.Value.Type,
Example = prop.Value.Example,
};

For anyone using Swashbuckle with ASP.NET, you can use the following code to have the $ref construct put under the allOf (just like the :
// do this wherever you are calling AddSwaggerGen()
ArgBuilder.Services.AddSwaggerGen(opts => {
opts.UseAllOfToExtendReferenceSchemas(); // add this line.
});
Now if you have a model with two properties of the same type, the individual descriptions for each field will show up in Swagger UI (e.g. below, both FooHeader and BarHeader are properties of type HttpHeader and their descriptions show up):

Related

OpenApi: how to describe error codes and messages?

I'd like to provide a series of custom codes and message for my error 400 but can't find any way to do so.
Ideally something like:
Error:
type: object
enum:
- [E01, 'Error1']
- [E02, 'Error2']
And so on
So I'm not sure that enums here can help you.
If you take a look over official documentation Enums are just strings, not object https://swagger.io/docs/specification/data-models/enums/ .
So my proposal is to use :
ErrorType:
type: object
properties:
code:
type: integer
name:
type: string
example: # Sample object
code: 10
name: Custom Error
Error:
type: object
properties:
errors:
oneOf:
- $ref '#/ErrorType'
- etc...
or directly without properties
Error:
type: object
oneOf:
- $ref '#/ErrorType'
- etc...
You can take a look for more examples on the official page https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
You can check out how Twitter has described it with $oneOf ( https://api.twitter.com/labs/2/openapi.json ) but unfortunately this convention is not easy nor supported by code generation tools like openapi-generator.
Until OpenApi supports enum descriptions (proposal is pending), one of the easiest ways are to:
define enum with all possible error codes
in the top level description: section of the spec define an inner section (with markdown notation #Error codes) that lists all error codes along with description.
Automated tool should check if the enum and description is consistent.

Swagger API errors: reference could not be resolved

I'm trying to specify my API data types in swagger 2.0 using yaml, but I'm getting a reference error (see error details at the bottom).
I'm using a nested structure, where the parent object (InvoiceConfigData) contains an array of child objects (ProviderVariantsData). This is the hierarchy of yaml files:
.api/swagger/cfg/InvoiceConfigData.yaml:
required:
- providerName
- providerVariants
properties:
providerName:
type: string
providerVariants:
type: array
items:
$ref: "#/definitions/ProviderVariantsData"
.api/swagger/cfg/ProviderVariantsData.yaml:
properties:
displayName:
type: string
cif:
type: string
availableTemplates:
type: array
items:
type: string
.api/swagger/definitions.yaml:
ProviderVariantsData:
$ref: ./cfg/ProviderVariantsData.yaml
InvoiceConfigData:
$ref: ./cfg/InvoiceConfigData.yaml
But I get the following errors:
API Errors:
#/definitions/InvoiceConfigData/$ref: Reference could not be resolved: ./cfg/InvoiceConfigData.yaml
#/definitions/ProviderVariantsData/$ref: Reference could not be resolved: ./cfg/ProviderVariantsData.yaml
API Warnings:
#/definitions/ProviderVariantsData: Definition is defined but is not used: #/definitions/ProviderVariantsData
There's something wrong in the way I reference the ProviderVariantsData, but I can't find what's causing the error. I've tried to flip the order in "definitions.yaml" (InvoiceConfigData above ProviderVariansData) without success.
swagger 2.0 doesn't support multiple YAML files.

SWAGGER: Dereferencing $ref from body parameter

Taking the petstore example,
I am trying to dereference the $Ref in the /pet -> put operation which is currently:
schema
$ref: #definitions/Pet
I am trying to resolve this but unable to get this text out from the json file.
This is what I have:
BodyParameter bp = (BodyParameter) param;
System.out.println(((RefModel) bp.getSchema()).get$ref());
I thought this would give me the above text out which I could later map with a definition Map and resolve it but got the following error:
Exception in thread "main" java.lang.ClassCastException: io.swagger.models.ModelImpl cannot be cast to io.swagger.models.RefModel
Would anyone know of a way to extract this string out from a body parameter and in general since the schema returns a Type Model?
I do not find a proper documentation source for the swagger parser , swagger inflector projects so hunting around through the source code itself.
you would do the following:
Model model = bp.getSchema();
if(model instanceof RefModel) {
RefModel ref = (RefModel) model;
String simpleRef = ref.getSimpleRef();
Model concreteModel = swagger.getDefinitions().get(simpleRef);
}
You should confirm that concreteModel is a ModelImpl but in the petstore case, it will be.

FSharp.Data.JsonProvider - Getting json from types

The FSharp.Data.JsonProvider provides a means to go from json to an F# type. Is it possible to go in the reverse direction i.e. declare an instance of one of the types created by FSharp.Data.JsonProvider, set the field values to be what I need, and then get the equivalent json?
I've tried things like this,
type Simple = JsonProvider<""" { "name":"John", "age":94 } """>
let fred = Simple(
Age = 5, // no argument or settable property 'Age'
Name = "Fred")
The latest version of F# Data now supports this. See the last example in http://fsharp.github.io/FSharp.Data/library/JsonProvider.html.
Your example would be:
type Simple = JsonProvider<""" { "name":"John", "age":94 } """>
let fred = Simple.Root(age = 5, name = "Fred")
This is one area where C# has an edge over F#, at least in Visual Studio. You can copy your JSON example code into the clipboard and in Visual Studio use the Edit -> Paste Special -> Paste JSON As Classes and it will create a class to match the JSON example. From there you can easily use the class in F#.
More details on paste special here
Hopefully a matching feature will come for F# soon too.

breezejs: how to access enum metadata

I've noticed that in the metadata there's an object entityType but also an object enumType.
We use manager.metadataStore.getEntityType() to access the metadata of an Entity.
How can we do it for a given enum ? How would I create the enum on the client side out of the metadata ?
Also, when I assign an enum value to a property, I'd like to to it by name instead of by value.
For instance, assuming that Status is of type myEnum:
myEntity.Status = myEnum.Valid;
instead of
myEntity.Status = 1;
Does breeze have any helper function to access the values of an enum ?
This issue is still open as I write. But you might want to take a look at the work-around described in the answer to this SO question.
I am assuming that you are talking about data properties that are defined as .NET enums on the server, and you want additional metadata about these properties to be made available on the Breeze client.
Unfortunately, Breeze does not yet support any metadata on enum types other than the name of the .NET type backing the enum value. This is the 'enumType' property that will appear on any dataProperty that is backed by an .NET Enum on the server. (We do need to document this better)
Please add a feature request for this to the Breeze User Voice. It's a good idea and we do take these suggestions very seriously.
Well this is not exact solution to your question but definitely can help people who are generating metadata offline.
I am using NancyFx(No EF) + Breeze + AngularJS for my web project and generating breeze metadata offline(using EF methods at development) and then using it in js file.
I also encountered similar situation where I want to get all Enum values to bind dropdowns and to display EnumName corresponding to EnumValue(Id). I searched over net but there was not much as per my scenario.
So I have written raw JS methods
1. To extract all enums and their values(Id & Name) in a JS dictionary(associated array) from metadata.
var enumDictionary = {};
JSON.parse(window.app.metadata).schema.enumType.forEach(function (enumType) {
var newEnumValues = [];
enumType.member.forEach(function (enumValue) {
var newEnumValue = { id: enumValue.value, name: enumValue.name };
newEnumValues.push(newEnumValue);
});
enumDictionary[enumType.name] = newEnumValues;
});
I created a method to get all enum values for a specific enum. This will be used for binding a dropdown.
function GetEnumDictionary(enumName) {
return enumDictionary[enumName];
}
Another method I created to get specific Enum name on basis of value.
function GetEnumDictionaryValue(enumName, enumValueId) {
var result = null;
enumDictionary[enumName].some(function (enumValue) {
if (enumValue.id == enumValueId) {
result = enumValue.name;
return;
}
});
return result;
}

Resources