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

Parameters for Media Types #2342

Open
cjaccino opened this issue Sep 6, 2020 · 4 comments
Open

Parameters for Media Types #2342

cjaccino opened this issue Sep 6, 2020 · 4 comments

Comments

@cjaccino
Copy link

@cjaccino cjaccino commented Sep 6, 2020

Parameters for Media Types

Media Types can support parameters. Yet, to work with them in OpenAPI, one must define them statically against each media type. This has the unfortunate side effect of discouraging use of media type parameters by making them clumsy to manage within the API spec.

content:
  text/plain; charset=utf-8:
    ...
  text/plain; charset=iso-8859-1:
    ...

Without a way to express the parameter, it has little or no semantic value for OpenAPI. Minor variations look like completely different media types. There is little room for negotiation over content parameters unless the API author takes the time to spell out each supported parameter as its own type.

Media Type parameters could be useful in some obvious ways:

  • versioning of the media type
  • specifying a 'profile' for the media type as described in RFC6906
  • negotiating support for embedded resources (i.e. HAL (https://tools.ietf.org/html/draft-kelly-json-hal-08)) , hypermedia style, or level of completeness of a representation.

Private and vendor media types might better manage breaking changes by supporting multiple versions of representation without ever changing endpoints and methods. Perhaps there could be benefits to QA and regression test tooling, being able to validate support for the diversity of representation styles in the API contract. This could be had without having to iterate every parameter combination as a separate media type.

Examples

Versioning

Accept: application/vnd.example-schema+json; version=1.0.4
content:
  application/vnd.example-schema+json:
    parameters:
      version:
        type: string
        required: false
        description: |
          The version of the representation.
        default: 1.1.0
        enum:
          - 1.0.3
          - 1.0.4
          - 1.1.0
    schema:
    	$ref: "https://schemas.example.com/example"

Profile identification

Accept: application/vnd.example-schema+json; profile=https://schemas.example.com/example/profiles/bob
content:
  application/vnd.example-schema+json:
    parameters:
      profile:
        type: string
        required: false
        description: |
          The profile (rfc6906) for the representation.
        default: "https://schemas.example.com/example/profiles/alice"
        enum:
          - "https://schemas.example.com/example/profiles/alice"
          - "https://schemas.example.com/example/profiles/bob"
    schema:
    	$ref: "https://schemas.example.com/example"

Hypermedia style selection

Accept: application/vnd.example-schema+json; hypermedia=HAL
content:  
  application/vnd.example-schema+json:
    parameters:
      hypermedia:
        type: string
        required: false
        description: |
          Hypermedia Style.  Indicates whether links and other supplemental
          resource detail are provided in the representation.
        default: JSON_HYPERSCHEMA
        enum:
          hypermedia:
            - NONE
            - HAL
            - JSON_HYPERSCHEMA
    schema:
    	$ref: "https://schemas.example.com/example"

Added after the original issue report
I am inspired by what I read on Roy Fielding's blog entry "REST APIs must be Hypertext Driven".

"A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]"

If I understand him correctly, enriching OpenAPI's ability to semantically express media type parameters would improve its ability to convey the kinds of interactions Mr. Fielding expected to be inherent in the resource or resource representation, rather than in other parts of the HTTP message. Conversely, not supporting media type parameters might limit OpenAPI's ability to articulate a nuanced RESTful concept.

@philsturgeon
Copy link
Contributor

@philsturgeon philsturgeon commented Nov 4, 2020

I'm right there with you on parameters and your examples for versioning and profile identification, but I think the hypermedia selection stuff is non-standard and we don't want to add anything non-standard to OpenAPI thats going to live in the users actual API.

If we stick the a general mechanism for adding parameters to a media type, I think this could be a great idea. charset, version, etc are all good things to be able to describe as possible in an API.

@cjaccino
Copy link
Author

@cjaccino cjaccino commented Nov 4, 2020

Thanks Phil.
You're right, the hypermedia example is flawed. I'm happy to remove it from the issue or provide other examples if it's helpful.

@MikeRalphson
Copy link
Member

@MikeRalphson MikeRalphson commented Nov 4, 2020

For consistency, if someone does take this to a PR, fields like type and enum should be wrapped within a standard schema field of type schemaObject.

@cjaccino
Copy link
Author

@cjaccino cjaccino commented Nov 4, 2020

Right. All of the examples need work.

The operation parameters field may be the best thing to compare for consistency.

Guessing at the changes that might be needed:

  • A new Media Type Parameter Object. Or possibly a subset of the existing Parameters Object?
  • Add parameters to the Media Type Object whose type would be Map[Media Type Parameter Object | Reference Object].
  • JSON Schema updates. Happy to propose these; would be looking for advice on norms for contributing to the project beyond issue contributions.

Revised Examples

Versioning

Accept: application/vnd.example-schema+json; version=1.0.4
content:
  application/vnd.example-schema+json:
    parameters:
      - name: version
         description:  Media type version for the representation.
         required: false
         deprecated: false
         schema:
           type: string
           default: 1.1.0
           enum:
             - 1.0.3
             - 1.0.4
             - 1.1.0
         examples:
           priorVersion:
             summary:  The most recent prior version.
             value: 1.0.4
           currentVersion:
             summary:  The current version.
             value: 1.1.0

or

content:
  application/vnd.example-schema+json:
    parameters:
      - $ref: "https://schemas.example.com/example/MediaTypeVersion"

Profile identification

Accept: application/vnd.example-schema+json; profile=https://schemas.example.com/example/profiles/bob
content:
  application/vnd.example-schema+json:
    parameters:
      - name: profile
       description: The profile (rfc6906) for the media type
       required: false
       deprecated: false
       schema: 
         type: string
         default: "https://schemas.example.com/example/profiles/alice"
         enum:
           - "https://schemas.example.com/example/profiles/alice"
           - "https://schemas.example.com/example/profiles/bob"
        examples:
          BobProfile:
            summary:  The classic Bob profile we all know and love.
            value: "https://schemas.example.com/example/profiles/bob"
          AliceProfile:
            summary:  The new and improved.
            value: "https://schemas.example.com/example/profiles/alice"

Use of value, not externalValue, as the value is intended to be the URL string, not the profile schema to which the URL refers. Interested if there are disagreements.

or

content:
  application/vnd.example-schema+json:
    parameters:
      - $ref: "https://schemas.example.com/example"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.