OAI / OpenAPI-Specification

The OpenAPI Specification Repository
https://openapis.org
Apache License 2.0
28.87k stars 9.07k forks source link

Extra JSON Reference properties ignored - reduces reusability of references #556

Closed JimJafar closed 4 years ago

JimJafar commented 8 years ago

Hi everyone.

I feel that the ignoring of extra properties when using JSON References goes against the goal of reusability.

Take this example from a fictional Swagger contract:

{
    addresses: [
        "homeAddress": {
            "description": "The premises at which electricity is provided.",
            "$ref": "#/definitions/Address"
        },
        "invoiceAddress": {
            "description": "The billing address - must be where the customer's credit card is registered.",
            "$ref": "#/definitions/Address"
        }
    ]
}

The "description" properties help to distinguish between the two uses of the "Address" Reference. Of course you could argue that better naming of the "homeAddress" and "invoiceAddress" properties could achieve this, but we are not always in control of property names in our data models and sometimes you need a more verbose description.

The Swagger editor (http://editor.swagger.io/#/) is an example of an application that could be improved by removing this limitation.

Is this something that has been raised previously? Please see here for a discussion on the Swagger Google Group: https://groups.google.com/forum/#!topic/swagger-swaggersocket/ewgimdO2cOI

pierslawson commented 7 years ago

@tadhgpearson I wouldn't necessarily expect the descriptions to be appended... I'd leave it down to the UI to decide how they should be displayed as it can access them both. It appears to me that swagger ui could, for example, just display the property level description where it currently displays the description of a primitive property and continue to show the referenced type's description within its model section.

I guess my thoughts come from not thinking of this as "overwriting" the referenced type's properties... rather it is documenting this use of the referenced type. If it was "overwriting" then either it is indicating this is a "sub class" of the referenced type (which doesn't feel right as we aren't intending to change its inherent makeup) or it is changing the global definition of the referenced type (which doesn't feel right either as each $ref to the referenced type would change that global definition, in turn leaving only one as the winner).

pierslawson commented 7 years ago

My worry about the proposal to limit the additional elements allowed alongside a $ref (as mentioned above by @handrews) is that won't help me with my xml issue and somebody is bound to want to add more items to the list... such as readonly etc. that are extensions to the underlying JSON Schema.

Does anyone know the reasoning behind the restriction being there in the first place?

Relequestual commented 7 years ago

I believe the restriction was initially to keep the JSON Schema specification simple.

It's actually pretty complex in terms of rule making to determine what behaviour should be expected when merging elements under various conditions. I won't go into details as that's been done a few times now already over on the JSON Schema repo issues. BUT, it is something we want to solve. (I believe we've added it to the draft-7 milestone) What would be most useful for now is if you could document exactly and as simply as possible, what your use case is.

handrews commented 7 years ago

Originally, JSON Reference was a separate specification intended for use independent from JSON Schema. This general problem is definitely a top priority for draft-07.

pierslawson commented 7 years ago

Funnily enough I went back to look at when I was last involved with the JSON Schema back in 2010... and my contributions then were around $ref!

I think at the time JSON references were just a concept rather than something somebody had tried to specify in their own specification. Version 04 dropped my wording to simply refer to the 2011 draft specification for JSON Reference. The even later draft specs for JSON Schema seem to have adopted a more stringent usage.

I'm not sure what thinking went into the change between versions 03 and 04... whether it was a well thought through adoption of the JSON Reference draft spec or just an assumption that the JSON Reference spec must capture the same concept that had been in version 03 of the JSON Schema spec. Either way... I think life might have been easier if we had adopted a type: schema alongside string, number etc. Then the reference could have been encapsulated in its own node.

Enough on that... I'll work on a use case.

pierslawson commented 7 years ago

@Relequestual - quick background: I have an existing API that can provide HTML, JSON and XML representations. I'm migrating it to ASP.Net Core and decided to take advantage of https://github.com/domaindrivendev/Swashbuckle.AspNetCore to create a resource that would expose a swagger.json document. It worked great except when I looked at the sample XML generated by swagger.io.

So here is the full contents of swagger.json for a pretty basic API that mixes up string based properties and object based properties:

{
  "swagger": "2.0",
  "info": {
    "title": "People Service",
    "version": "v1"
  },
  "basePath": "/",
  "paths": {
    "/parents/{id}": {
      "get": {
        "tags": [ "Parents" ],
        "summary": "Retrieves a specific parents.",
        "consumes": [],
        "produces": [ "application/xml", "application/json" ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "Parent retrieved.",
            "schema": { "$ref": "#/definitions/parent" }
          }
        }
      }
    }
  },
  "definitions": {
    "parent": {
      "type": "object",
      "properties": {
        "childStr": {
          "type": "string",
          "xml": {
            "name": "ChildStr"
          }
        },
        "childObj": {
          "$ref": "#/definitions/childObject",
          "xml": {
            "name": "ChildObj"
          }
        },
        "childStrings": {
          "type": "array",
          "items": {
            "type": "string",
            "xml": { "name": "ChildString" }
          },
          "xml": {
            "name": "ChildStrings",
            "wrapped": true
          }
        },
        "childObjects": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/childObject",
            "xml": { "name": "ChildObject" }
          },
          "xml": {
            "name": "ChildObjects",
            "wrapped": true
          }
        }
      },
      "xml": {
        "name": "Parent"
      }
    },
    "childObject": {
      "type": "object",
      "properties": {
        "value": {
          "type": "string",
          "xml": {
            "attribute": true
          }
        }
      }
    }
  }
}

The sample XML produced by swagger.io is currently:

<?xml version="1.0" encoding="UTF-8"?>
<Parent>
    <ChildStr>string</ChildStr>
    <childObj value="string">
    </childObj>
    <ChildStrings>
        <ChildString>string</ChildString>
    </ChildStrings>
    <ChildObjects>
        <ChildObjects value="string">
        </ChildObjects>
    </ChildObjects>
</Parent>

As per the current spec, there are two warnings about two of the xml values being ignored as they are alongside a $ref.

I would like to see the following XML generated (i.e. those xml nodes not being ignored and simply treated the same way as the xml nodes alongside the string based values are treated):

<?xml version="1.0" encoding="UTF-8"?>
<Parent>
    <ChildStr>string</ChildStr>
    <ChildObj value="string">
    </ChildObj>
    <ChildStrings>
        <ChildString>string</ChildString>
    </ChildStrings>
    <ChildObjects>
        <ChildObject value="string">
        </ChildObject>
    </ChildObjects>
</Parent>

In case you can't spot the differences:

  1. childObj is now ChildObj
  2. ChildObjects contains a list of ChildObject not a list of ChildObjects

This is pretty similar use case to the original one highlighted by @JimSangwine

handrews commented 7 years ago

@pierslawson I can't speak to what happened between drafts 03 and 04. No one who was active with JSON Schema at the time is still involved.

For draft-05, the goal with core and validation was improved clarity, so it just pulled in exactly what the separate JSON Reference draft specified. And we did not significantly change that for draft-06. The only real change that resulted from pulling it into the JSON Schema spec (again) is that we specified that it can only be used where a schema is expected (there is also a proposal for draft-07 hyper-schema to allow it where a link description object is expected as well).

Loosening the $ref rules is one of several proposals on the table for draft-07.

Relequestual commented 7 years ago

@pierslawson Is the xml part something designated by swagger? not seen it before in a json schema.

pierslawson commented 7 years ago

@Relequestual it is part of the Open API Specification https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#xml-object which swagger is built against.

nickreevesuk commented 7 years ago

They key issue is that $ref represents a BINARY relationship with two ends the referee and the referent. There are many genuine needs to attach meta data describing the referee not the referent. So if Customer entity has a reference to an Address you need a descriptions such as "this address is the billing address" or "this address is the electricity supply address". These are not overriding the description of the referent (what an address is), but giving information about the specific use in the referee (what this address instance represents). This goes beyond description to many other pieces of meta data describing the use in the referee (whether that reference is mandatory, what version it was introduced at ...) which can legitimately vary between references to the same referent.

Thus any complaints around not being able to allow other sibling properties to $ref because they would conflict with ones on the referent are specious. You simply need to define the semantics of these properties as applying to the specific use in the referee, leaving the referent unchanged. If you want to add properties relating to the referent those would be done in the referent at its point of definition.

Relequestual commented 7 years ago

@nickreevesuk That's an easy to understand and compelling use case. We're ON IT.

You could get around this currentley by having two layers of references I believe.

ePaul commented 7 years ago

You could get around this currentley by having two layers of references I believe.

I don't think so ... each layer of $ref ignores all other properties.

What I've seen sometimes is misusing allOf:

Customer:
  type: object
  properties:
    billingAddress:
      description: "the address to which the bill is sent"
      allOf:
       - $ref: '#/definitions/Address'
    supplyAddress:
      description: The address where the electricity is supplied
      allOf:
       - $ref: '#/definitions/Address'
Relequestual commented 7 years ago

mmm. I'm not sure quite what I was thinking =/

RicoSuter commented 6 years ago

I'm working on the .NET Swagger toolchain NSwag and I have the same issue (also see https://github.com/Azure/autorest/issues/2652).

Currently the toolchain produces

    supplyAddress:
      description: The address where the electricity is supplied
      allOf:
       - $ref: '#/definitions/Address'

Why is this a misuse? The description of the parameter is not an override but a description of the property - the description of the Address describes the schema/class itself.

My options are:

I still think @IvanGoncharov proposal is the best solution. Its important for me to find consensus here so that we can invite all tools to behave the same way and we can link to this decision.

For example, we could define the following rules which everyone should follow:

I think it is important to define the rules for this scenario somewhere, so that every tool can be implemented in the same way. As it is currently, a Swagger spec is not really universally usable...

Has this been fixed with Open API 3?

handrews commented 6 years ago

@RSuter and all: The forthcoming draft-07 of JSON Schema (hopefully next month) will have a bit more guidance on keywords like title, description, default, examples, readOnly, and secret, which we are calling annotation keywords. This isn't really a new mandatory implementation requirement, and is compatible with earlier drafts (for whatever keywords were present in the earlier drafts- only the first three of those were in draft-04, plus readOnly was in Hyper-Schema at the time).

We are defining how an implementation can and should collect multiple values of these keywords when they apply to the same part of the instance, and making it more clear that applications should interpret the results as needed.

For instance, a system could discard all descriptions except the top-most one (e.g. keeping the one outside of an allOf and ignoring the ones within it). Or a system could append them all into a multi-paragraph description. The JSON Schema spec does not determine this, so OpenAPI could choose a particular behavior on top of this basic value-collection behavior for consistency.

Then, if OpenAPI chooses something like "concatenate all descriptions in depth-first order", or even something more content-specific like "check for a section number and order them accordingly", OpenAPI document authors can write descriptions with those processing rules in mind.

The PR is https://github.com/json-schema-org/json-schema-spec/pull/424 if anyone would like to give feedback.

This is much simpler than defining schema-merging semantics, which continues to be a bitterly divisive topic. Hopefully it will be addressed in draft-08 (either added or definitively rejected, but either way not in a state of limbo anymore). Although I'm not sure who is going to run that draft on the core and validation side as I will be focusing on hyper-schema.

darrelmiller commented 6 years ago

I have a slightly different proposal to address this particular problem. And perhaps this should be in the JSON-Schema repo instead. Let me know @handrews

Considering the example shown by @RSuter above:

supplyAddress:
      description: The address where the electricity is supplied
      allOf:
       - $ref: '#/definitions/Address

and building on @nickreevesuk 's description of $ref as a relationship between what I'll call the source and target because I will keep confusing referee and referent :-)

Let's look at an example of a media type that already does transclusion much like we are trying to do. Consider a standard HTML page:

<html>
    <link rel="stylesheet" title="My bedazzling style" href="stylesheet.css" />
</html>

The link tag defines a relationship between the source HTML page and target CSS file to be transcluded. The additional attributes on the link tag further qualify the relationship. They DO NOT change the target CSS. In fact the attributes on the link tag are not related to the structure of the target object. They are native properties of the link itself.

My understanding is that much of the pain we are experiencing is related to us trying to modify the target of the $ref using properties in the source. Do we really need to do that? Could we annotate the object that contains the $ref property with additional metadata to describe the relationship?

e.g.

supplyAddress:
      $ref: '#/definitions/Address
      title: The address where the electricity is supplied

I realize this is not currently valid JSON Schema, and it looks very similar to what has already been proposed and what many people already do, ignoring the fact that it is currently invalid. However, the important distinction is that the property I have added would need to be a defined property of a "reference object". It is not an attempt to merge with the target object. It is an attribute of the relationship.

This approach addresses a major concern of mine that I haven't seen much conversation around. If I am writing tooling that loads an OpenAPI description into memory, when I have 1400 operations that all $ref a shared parameter, do I maintain that reference in the object graph, or do I inline the parameter definition? Obviously just maintaining the reference is ideal. However, if I have to merge a property that is overridden in every operation, I may have little choice but inline the parameter objects. Either that or create some fancy decorator object that wraps the target object.

If the reference object itself can maintain the additional annotations, then there only needs to be a single instance of the target object.

Now, what attributes are appropriate for this kind of reference object I don't know, but we do have some precedent on the subject in RFC5988.

handrews commented 6 years ago

@darrelmiller let's keep the discussion here for just a bit, and if it really digs into $ref proposals I'll find the right JSON Schema issue for you to add to (or let you know if you should file a new one).

This approach addresses a major concern of mine that I haven't seen much conversation around. If I am writing tooling that loads an OpenAPI description into memory, when I have 1400 operations that all $ref a shared parameter, do I maintain that reference in the object graph, or do I inline the parameter definition? Obviously just maintaining the reference is ideal. However, if I have to merge a property that is overridden in every operation, I may have little choice but inline the parameter objects. Either that or create some fancy decorator object that wraps the target object.

Yeah, this about sums it up. There's some confusion here, too, as the old separate JSON Reference I-D allowed implementations to replace the reference with the target, that actually doesn't quite work in JSON Schema (due to base URI inhereitance and meta-schema working within the target file / structure rather than inheriting across the $ref).

Let me float a syntax here, in addition to the current syntax, and then explain it in the context of recent JSON Schema work:

$ref:
    href: "#/definitions/Address"
    title: "The address where the electricity is supplied."
    description: "Lots and lots of text here ..."

The idea here is that you would still be able to use $ref as you do now, with a string value that is a URI reference, for simple cases. But if you want to get full link functionality, then the value of $ref is an object letting you specify a lot more attributes. This particular syntax is a very, very stripped-down subset of Hyper-Schema's LDO, which will likely get some more target attributes defined that could be used here (might as well argue them in one place...)

To be absolutely clear: none of the URI templating or input description keywords would be allowed in this context. The idea is not to use Hyper-Schema itself, just a compatible subset. While rel is required in Hyper-Schema, it seems unlikely to be useful here, so I would probably assign it the default value of "related" (which is an IANA-registered relation). I suppose anchor could be used, but I can't imagine why it would be off the top of my head.

What I like about this is that it's not possible to confuse this with a schema merge strategy, and it suggests the correct mental model of web linking.

handrews commented 6 years ago

If this gets any traction, we can file it as a proposal on JSON Schema. $ref changes are a source of contention, but this at least aligns $ref with an existing well-known concept.

darrelmiller commented 6 years ago

@handrews That approach works for me too. I was adding to the existing reference object just to reduce the nesting a bit, but your solution is definitely clearer as to what is going on.

handrews commented 6 years ago

@darrelmiller cool! I'm going to think on it for a couple of days, and if it holds up, I'll file it in the JSON Schema repo. You're of course welcome to open an issue yourself if you'd rather. I've kind of exhausted the capacity of everyone else to review things at the moment with the top-to-bottom hyper-schema rewrite :-P

Anyone: feel free to remind me if I don't do something about it within a week.

Relequestual commented 6 years ago

@handrews Did you make any suggestions on this within the JSON Schema repo? (I have nearly 2k github notification emails... forgive me for not knowing or checking ;) )

(I guess that means you should also probably notify me on slack or something if you reply!)

handrews commented 6 years ago

@Relequestual I plan to file it this week or next. Draft-07 is out as of yesterday! I'm tidying up the web site and putting together migration notes and will announce it more broadly. Then this is one of several draft-08 backlog items I need to file that I was avoiding doing b/c I did not want to start a big discussion while wrapping up draft-07.

handrews commented 6 years ago

@darrelmiller @Relequestual I've referenced this from a JSON Schema issue. The JSON Schema issue is rather abstract, focusing on how $ref should be processed. I'd like to see how that goes, as well as a separate proposal for deferred evaluation keywords that may solve a lot of re-use problems (warning- that issue is even more abstract, laying out a full JSON Schema processing model and proposing extensions).

With draft-07 we formally organized JSON Schema keywords by behavior into the (in some cases overlapping) classifications of applicability, assertions, and annotations. This has given us a better framework to talk about changes to JSON Schema behavior.

I'm hoping to get these processing model questions resolved early in draft-08 and then move into concrete discussions of what to do about specific ongoing re-use concerns. We'll see how that goes.

handrews commented 6 years ago

[Apologies for some duplicate info in various issues as I update with JSON Schema developments- I'm never sure if people, particularly lurkers, are following all the issues or just selected ones]

@darrelmiller it looks like we will probably go with something more like your proposal for adjacent keywords.

Specifically:

Basically, we'll define the process so that it's easier to figure out how the information is arranged in the schema, and avoid defining the usage semantics too closely to give downstream systems the ability to define a wide range of reasonable semantics.

As for the link serialization approach, I think it's still reasonable to think of $ref as a hyperlink, but moving to a specific syntax related to hyper-schema LDOs adds complexity without adding much functionality. Let's see how things work with the simpler approach first.

tadhgpearson commented 6 years ago

That sounds good @handrews, but could you give us a specific example of how this would look in practice?

handrews commented 6 years ago

@tadhgpearson this isn't finalized yet, but the general idea is that in addition to the boolean validation outcome, JSON Schema implementations should also return annotation data (although disabling annotation collection for optimizing validation-only should probably be allowed). Then, applications (in this context, all OpenAPI-based tools are applications) can make their own choices about how to handle things.

So let's have a schema:

{
    "type": "object",
    "properties": {
        "foo": {
            "title": "Title adjacent to reference",
            "description": "Lots of text",
            "readOnly": true,
            "$ref": "#/definitions/fooDef"
        }
    },
    "definitions": {
        "fooDef": {
            "title": "Title in reference target",
            "description": "Even more text"
        }
    }
}

With an instance of:

{
    "foo": "whatever"
}

The annotation results might look like this (it's still up in the air, for instance I literally made up how $ref appears in the JSON Pointer-ish thing while typing this comment):

{
    "/foo": {
        "title": {
            "/properties/foo/$ref/title": "Title in reference target",
            "/properties/foo/title": "Title adjacent to reference"
        },
        "description": {
            "/properties/foo/$ref/description": "Even more text",
            "/properties/foo/description": "Lots of text"
        },
        "readOnly": true
    }
}

"/foo" is the instance pointer- this is the place in the instance to which the annotations apply.

Under that, the property names are the names of each annotation. All of these are also the keyword names that produced them, but in theory you could do something that doesn't map directly (please allow me to wave my hands on that- it's related to a complicated proposal that's under discussion and may not end up being relevant).

Under each annotation, the format is determined by the annotation.

readOnly just has a boolean, because it's explicitly stated (as of draft-07) that the overall value of readOnly is a logical OR of all applicable values. So there's no need to keep track of which value came from where- just let the application know the final outcome.

On the other hand, the way "title" and "description" are shown here is probably the default behavior. For those, "/properties/foo/... are schema pointers, more or less. Pointing across $ref is a bit weird and I need to figure out if that's the right approach. But however it ends up looking, you will be able to tell where the annotation came from so your application can decide how to use it.

So let's say your application decides that a local title always wins over a referenced title, but descriptions should just be concatenated as if each were a paragraph. There is enough information in the above format that you can tell that "Title adjacent to reference" is the title that wins, and then you can construct "Lots of text\n\nEven more text" from the various descriptions.

This is because there are many ways that an application might want to handle multiple titles / descriptions / defaults / etc: closest to root wins, most specific wins, combine them somehow, throw an error, whatever. Depending on the application and the keyword, any of these could be reasonable.

I would expect a system like OpenAPI to pick strategies for consistency. So then an OpenAPI implementation could use a regular old JSON Schema implementation to gather the annotations, then examine them to resolve any ambiguities however OpenAPI thinks they should be resolved. And then other applications can still use JSON Schema and resolve ambiguities differently.

There will no doubt be further debate about how much to standardize and how much to defer to applications, but that's a lot better than the current situation where there's not even any guidance on what sort of decisions are valid to make, much less any implementation requirements to facilitate making them.

handrews commented 6 years ago

@tadhgpearson & everyone:

json-schema-org/json-schema-spec#523 discusses keywords alongside of $ref json-schema-org/json-schema-spec#530 discusses more of the process of annotation collection

Both are targeted for draft-08, hopefully by the end of May.

Relequestual commented 6 years ago

Keywords alongside $ref now has an open PR against. So I can't imagine it won't be included in draft-8.

sgeeroms commented 6 years ago

I found this thread, and for me it should be possible to added description sibling next to a ref$ tag. This is mainly usefull if you reference a simple types and not objects.

If you define a base type like for example:

  IPAddressV4:
    type: string
    format: ipv4
    pattern: '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'

And you use this type in a object, for example

  DualPortServer:
    type: object
    description: Server with two ports     
    required:
      - ipAddress1
    properties:
      managementPort:
        $ref: '#/definitions/IPAddressV4'
        description: LAN management port for configuring the server
      ipAddress1:
        $ref: '#/definitions/IPAddressV4'
        description: Primary (mandatory) transfer ethernet IP address.
      ipAddress2:
        $ref: '#/definitions/IPAddressV4'
        description: Secundary (optinal) transfer ethernet IP address.

Maybe I am not doing this the right way? But if so it would be nice to be able to set a specific description.

hkosova commented 6 years ago

@sgeeroms please see this comment.

sgeeroms commented 6 years ago

@hkosova, Thanks a lot! Didn't know the "allOf" could be used for simple fields as well.

bobvanderlinden commented 5 years ago

I ran into this issue because swagger 1.2 does support property descriptions where there is a reference to a different type:

{
  "properties": {
    "myProperty": {
      "type": "MyModel",
      "description": "Description of property"
    }
  }
}

In addition, swagger-converter (swagger 1.2 -> openapi 2.0 converter) generates the following from this definition:

{
  "properties": {
    "myProperty": {
      "$ref": "#/definitions/MyModel",
      "description": "Description of property"
    }
  }
}

This is not according to the openapi 2.0 specification. api-spec-converter gives a warning for the description field, as it resides next to $ref. Other tools often ignore the description.

ghost commented 5 years ago

Hi My Project has user defined classes for Duration, Cost, etc and these are being used as nested fields in other schema classes and I need to give description to each nested fields which is referenced to that class and I am using swagger-annotation to generate docs. I tried the allOf but it didn't work.

E.g: class Duration{ int value; int text; }

@Schema class OfficeSchedule{ int val; String name; Duration startDuration; Duration endDuration;

public int getVal(){ return val; }

public String getName(){ return name; }

@Schema(description = "start duration of office schedule", accessMode = AccessMode.READ_ONLY) public Duration getStartDuration() { return startDuration; }

@Schema(description = "end duration of office schedule", accessMode = AccessMode.READ_ONLY) public Duration getEndDuration() { return endDuration; } }

I tried using allOf but Json stillis not giving referenced class property description and updating the same schema description and the last property with

Json Schema Output

"Duration": { "title": "Duration", "type": "object", "properties": { "double": { "type": "number", "format": "double" }, "bigDecimal": { "type": "number" } }, "description": "end duration of office schedule", "readOnly": true, "allOf": [ { "$ref": "#/components/schemas/Duration" } ] }

Above example is a sample and almost all classes declared for our project are being used internally in other classes as fields. Can anyone help with this I need to provide referenced property level descriptions?

Arbuste commented 5 years ago

Hi, just adding one instance of reusaility need here.

My own personal need is to change the required fields of an object depending on which service it is requested in.

I tried to use the allOf trick but as I expected this is not well handled by the client generator. Anyway, I think this is not the purpose of the allOf element.

RicoSuter commented 5 years ago

I'd expect that this (OpenAPI 3)

"startLocation": {
    "description": "The location of the trip start.",
    "nullable": true,
    "oneOf": [
        {
            "$ref": "#/components/schemas/Location"
        }
    ]
},

or this (Swagger 2)

"startLocation": {
    "description": "The location of the trip start.",
    "allOf": [
        {
            "$ref": "#/components/schemas/Location"
        }
    ]
},

should be allowed, but eg. swagger-codegen does not allow this. Why is one of these samples not the current way to go? Or something similar to avoid $ref with additional properties?

hkosova commented 4 years ago

In Schema Objects, $ref siblings will be supported in OAS 3.1 which will use the JSON Schema 2019-09. As mentioned in JSON Schema 2019-09 release notes, it now allows keywords alongside $ref.

However, this change does not affect $refs outside of Schema Objects, such as $refs in parameters or responses.

Related: #2099

philsturgeon commented 4 years ago

As @hkosova mentions, siblings are now welcome in schema objects, and will likely be allowed in various other places around the OpenAPI spec.

thejeff77 commented 1 year ago

I think that a good solution here would be to split the definition of description. you could split into field description and class description.