Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Schema Object example and Media Type example #2336

Closed
wants to merge 1 commit into from

Conversation

philsturgeon
Copy link
Contributor

@philsturgeon philsturgeon commented Sep 3, 2020

There are too many types of examples currently in OpenAPI, v3.1 is going to see another one come in as part of JSON Schema 2019-09.

In OpenAPI v3.1, here are all the places you could put examples just for a response:

/infinite-examples:
  get:
    operationId: infinite-examples
    responses:
      "200":
        description: OK
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  # OpenAPI Schema Object Example
                  example: stowford
                coordinates:
                  description: We couldn't pick a format for coordinates so we support
                  pretty much all of them.
                  # JSON Schema Examples from 2019-09
                  examples:
                  - "52.377956, 4.897070"
                  - [52.377956, 4.897070]
                  - { lat: 52.377956, lon: 4.897070 }
              required:
                - name
                - coordinates
              
              # OpenAPI Schema Object Example (but for an object)
              example:
                name: freddy
                coordinates: "52.377956, 4.897070"

            # OpenAPI Media Type Example
            example:
              name: finn
              coordinates: "52.377956, 4.897070"

            # OpenAPI Media Type Examples
            examples:
              arbitrary example name:
                value:
                  name: finns evil twin
                  coordinates: "52.377956, 4.897070"   

Thankfully "OpenAPI Media Type Example" and "OpenAPI Media Type Examples" are a xor so its always going to be one or the other, but this is still really complex for tool maintainers to support. Over at Stoplight it's caused untold confusion, and we're still not quite supporting all of them correctly despite various attempts to get it right, and with v3.1 adding more it's just going to make our tooling and our user interfaces more complicated.

We can cope with being confused, but I think it's generally bad for the ecosystem: tooling vendors and end users alike, to have umpteen different ways to do the same thing.

So, I propose getting rid of 2/5 types of example:

  1. example in the Schema Object
  2. example in the Media Type / Parameters

1 seems easy. Yes, it's a little more typing to write:

examples: 
- stowford
# or 
examples: [stowford]

instead of

example: stowford

but we're already deprecating it, and just like nullable, let's kill it instead of dragging it out.

Deprecated: The example property has been deprecated in favor of the JSON Schema examples keyword. 👋

As for media type example and parameter example, that's an easy one too, because again folks can use examples in the OpenAPI form: Map[string, [Example Object](#exampleObject) \| [Reference Object](#referenceObject)], or they can do example stuff inside the schema (using examples in the JSON Schema-ish way).

Whatever we do, taking an axe to some of these 5 approaches will be helpful for end users and tooling vendors who are just tying to figure out how to show examples, in docs, mocks, etc.

For more insight into the plethora of examples we currently have, I done a giant blog post. You'll laugh. You'll cry. You'll have questions. https://phil.tech/2020/openapi-examples/

@philsturgeon philsturgeon changed the base branch from master to v3.1.0-dev September 3, 2020 17:56
@philsturgeon philsturgeon changed the title Remove Schema Object "example" and Media Type example Remove Schema Object example and Media Type example Sep 3, 2020
@MikeRalphson
Copy link
Member

Some previous discussion in #953

@lornajane
Copy link
Contributor

I'm not sure how multiple examples would be used in practice, so I think I'm missing the value of making this change. Currently, OpenAPI expects a field to have a type, a description, an example (shaped like the type), maybe a default. It's simple to understand and I run into a lot of newcomers to OpenAPI for whom this is only just simple enough. If it's the general aim to adopt as much of a JSON Schema approach as possible then changing to match their example format could make some sense, but I'm not sure I've seen the usefulness for OpenAPI-only users. Especially not if those users aren't using a lot of helper tooling.

Where it does make sense to have multiple examples is in the responses, where more than one thing or type of thing might come back - it makes sense to me that we have multiple examples in that context. Does anyone have some use cases in mind where having multiple examples values on each field would be helpful? I am currently uneasy about this change so tell me what I haven't understood!

@handrews
Copy link
Member

@lornajane When we debated adding example or examples to JSON Schema years ago, we settled on examples as people had reasons for wanting it. It is sufficiently long ago that I do not recall the reasons, but if we want to both conform to standard JSON Schema (avoid contradicting the spec) and provide clear guidance on usage (there should be one right way to do it, if possible), then that means examples. We're not going to go change that 4 drafts and 5 years after adding it when it's never been reported as a problem to us over the years. Goodness knows people report plenty of other things 😅

Nothing's stopping people from supporting example if they're dead set on it, but the proposal here is that one recommendation is better than many, if you only want one that satisfies the two constraints I listed, then that's the one that it has to be.

I don't mean to be a grump, but no one gets everything they want in this. Sometimes it's more important to look at what constraints we want to satisfy than to look at the specific options. Then the question is "do we want to violate these constraints?" which is simpler than "which of these almost-the-same options, all of which have people who want or don't want them should we fight over for the next month based on personal opinions?" Because in my experience that's what happens. We can argue over how burdensome it is to add an s and put [] around the value or we can choose our constraints.

If we don't care about those two constraints then just leave it all in there I guess.

@darrelmiller
Copy link
Member

From TSC meeting:

  • example in OpenAPI Schema object should be seriously considered for removal. No objections raised except for Lorna who is concerned about removing example for a property.
  • example in Media Type Object should be less seriously considered for removal. The concern is about about the impact on readability/writeability.

Please add comments..

@@ -1029,11 +1029,11 @@ Field Name | Type | Description
<a name="parameterAllowReserved"></a>allowReserved | `boolean` | Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2) `:/?#[]@!$&'()*+,;=` to be included without percent-encoding. This property only applies to parameters with an `in` value of `query`. The default value is `false`.
<a name="parameterSchema"></a>schema | [Schema Object](#schemaObject) | The schema defining the type used for the parameter.
<a name="parameterExample"></a>example | Any | Example of the parameter's potential value. The example SHOULD match the specified schema and encoding properties if present. The `example` field is mutually exclusive of the `examples` field. Furthermore, if referencing a `schema` that contains an example, the `example` value SHALL _override_ the example provided by the schema. To represent examples of media types that cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where necessary.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the singular example for parameters, should we drop this as well, moving to the examples which can also be here?

@lornajane
Copy link
Contributor

Both @handrews comment above and today's discussion in the TSC call are illuminating and helpful (also if you didn't read Phil's post, it's well worth it). We reflected a bit on who is our main "target" when the needs of either not-specialist developer or not-complex APIs run into the depth of people who work on very complex projects, using JSON Schema. TSC by its very nature is mostly (and should be) populated by the latter group and I feel we do lose sight of the first group. This change definitely doesn't favour "ordinary" API publishers, but maybe "just pick one" is the best approach for both groups!

If we drop one example keyword, the simplest from an education point of view is to drop them all - the different structures of examples, some with and some without keys, is still a stumbling block but that is already here, we're not degrading anything. Can these changes be handled by conversion tooling? Are we planning to add this into the 3.1 release?

@philsturgeon
Copy link
Contributor Author

philsturgeon commented Sep 18, 2020

We reflected a bit on who is our main "target" when the needs of either not-specialist developer or not-complex APIs run into the depth of people who work on very complex projects, using JSON Schema. TSC by its very nature is mostly (and should be) populated by the latter group and I feel we do lose sight of the first group.

There's a bit of a confusing statement over there, suggesting that JSON Schema is for more complex projects. I'm not sure that's a fair differentiation. Yes later drafts of JSON Schema have some more powerful keywords available that were added after the version of JSON Schema that OpenAPI pegged to for v3.0, but it's not a "power users only" type of thing. OpenAPI suggests you can use JSON Schema keywords, so people consider the schema object to be JSON Schema, so they google for "how to do foo in JSON Schema" then do things that will make some tools fall over, and others support it. So more tools support an awkward mixture of both syntax, which perpetuates the idea that it's actually JSON Schema even though its not...

Beginners suffer the most from all this confusion, as they have to navigate the complexities of varying compatibility of different tools.

So JSON Schema is not for advanced people, its for anyone. Furthermore this change doesn't ignore beginners, it is focused on giving them one less approach to chose between, with the result of whatever we pick being clearly documented in the Getting Started Documentation so nobody has to be confused, and google around, finding disparate information based on all the different types of examples in different places across different versions of OAS2 and OAS3 and JSON Schema from blog posts going back years and years.

There's a few groups, personas, that I see.

  1. People writing OpenAPI YAML by hand
  • who are not very experienced, no idea what to write, keep googling things, finding mixed information
  • who are more experienced, who want to wear their keyboard out as little as possible writing the least YAML
  • who are more experienced, who do not mind a bit more typing to get more useful functionality (like providing multiple examples, even "paired examples" where you have requests, responses, and parameters with matching names to get reeeeeal specific with your examples)
  1. People writing OpenAPI with a GUI, DSL, or Annotations

Persona 1.i are being solved with Getting Started documentation.

Persona 1.ii (myself included) are going to have to suck it up and add a newline and a - for schema object examples (which hasn't caused any problems for the JSON Schema community) and use a dictionary for their examples, probably turning a few of them into 1.iii who were previously unaware that functionality even existed. For those who do not convert to that way of thinking, they can use schema examples to avoid writing Media Type dictionaries.

Persona 2 see no change at all.

Whether OpenAPI is aimed to be easier for humans or computers to use is then a separate conversation, because I will NEVER remember if its:

  • content.responses.application/json.200.schema
  • responses.application/json.content.200.schema
  • responses.application/json.200.content.schema
  • responses.application/json.content.200.schema

If we want to target OpenAPI to be easy for humans to read, write, and memorize, we need to start from scratch. That may have been an objective for Swagger 1.x but IMHO I think that objective might have failed somewhere between v2 and v3. Not a unique opinion.

This doesn't mean we should just throw readability out and always do everything in the more verbose way possible, but when it comes to a choice of "less typing" vs "improved functionality" we seem to pick the latter.

@handrews
Copy link
Member

I feel like this discussion is losing track of a key issue here: @lornajane is raising a very important general point. However, in this specific case, putting square brackets around something because it's a list and not a scalar is not a significant amount of complexity. It is not an unusual data structure. The syntax is simple and universal across all usages of JSON and many other systems. It is not being used in a non-intuitive way. It is exactly what it looks like: a list of examples.

When we talk about beginner vs advanced, "only one way to do it" is definitely pro-beginner. And while "scalar" may technically be easier than "list", I assert that particularly to a new beginning-level user, it is not a problem at all.

It is mildly confusing and more complex to people who are used to example, but in time this will go away and people will learn examples from the start. That steady state is what we should design for.

I would be more inclined to weigh complexity if we were, for example, talking about more options for explode, or a new way to organize Response Objects. Those things are not standard JSON data structures with standard JSON meanings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants