OAI / OpenAPI-Specification

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

Message format 'wrappers' #555

Closed jharmn closed 9 months ago

jharmn commented 8 years ago

Some existing hypermedia formats (such as JSON API, HAL, JSON Collection) define a standard 'wrapper' for responses (not unlike the old SOAP envelope, in some ways).

Current OpenAPI conventions are inconvenient and very redundant in describing these formats. An OpenAPI method of describing APIs with these formats would produce specs that are much DRYer.

https://github.com/OAI/OpenAPI-Specification/issues/136 https://github.com/OAI/OpenAPI-Specification/issues/519 https://github.com/OAI/OpenAPI-Specification/issues/522 https://github.com/OAI/OpenAPI-Specification/issues/476

Solutions are not described here yet, but this should serve as a point to consolidate concepts from prior feedback when evaluating potential solutions.

@darrelmiller input here would be great.

dilipkrish commented 8 years ago

@darrelmiller is probably more qualified to comment on this, but I'd like to suggest addressing what I believe are gaps in the spec:

  1. being able to describe link relations
  2. being able to describe additional response headers.
  3. being able to describe models in other dialects xml, bson, protobuf etc.

Just throwing an ideas out here for problem # 1 based on the pet store example, please excuse if its a bit contrived

  /pets:
    get:
      description:  description....
      operationId: findPets
      parameters:
        - name: tags
          in: query
          description: tags to filter by
          required: false
          type: array
          collectionFormat: csv
          items:
            type: string
        - name: limit
          in: query
          description: maximum number of results to return
          required: false
          type: integer
          format: int32
      responses:
        200:
          description: pet response
          headers: 
             # Location in the case of create resource  
             - name: "Location"
               description: Location of created resource
               type: string
             # Pagination headers
             - name: "totalPages"
               description: total number of pages
               type: integer
               format: int32
          body:
            type: array
            items:
              $ref: '#/definitions/Pet'
             # each link is a urlRef to another Path object, with a specific method
            links: 
             - rel: "create"               
               $urlRef: "#paths/pet"
               method: "post" 
             - rel: "delete"               
               $urlRef: "#paths/pet" 
               method: "delete" 
          ...

Also I find it odd, that we're trying to describe other rich media types within swagger. inception? :smile: If an api is using json-api or HAL, CJ, Apiary's Api Blue Print etc. for that matter; is there a need to describe it via swagger as well? I suspect there will be transformers for those cases in the future.

The second problem is a subtly different issue, but it also centers around media types. Take for e.g. people wanting to document an application/xml response in swagger. Is json schema the right choice for that? The current spec implicitly assumes json schema, may be we should try and make it easy to describe models in other dialects? I don't know what that would look like, but in the case of xml responses it would be better to directly use xsd rather than writing a "wrapper".

jharmn commented 8 years ago

On links: the only trouble with your example is that there is not a consistent link structure to rely on, as proposed. Resource a passion structures as in stormpath.com don't fit the 'rel' format.

It really seems like additional types, beyond 'object', would be required to resolve these wrappers.

On alternate media types beyond JSON, I'd propose that we tackle that discussion in a separate issue, to keep focused on the frequently discussed JSON based formats.

dilipkrish commented 8 years ago

By "Resource a passion" I presume you mean "Resource Expansion"? :)

Not sure what you mean by additional types, beyond 'object' example?. But like you said its worth breaking this issue into smaller focused issues

  1. Supporting other json based service description media types
  2. I think you're alluding to supporting projections, views, and excerpts of models. Projections include link expansions, excerpts of models in search results. different request, response models (some times models may differ when serializing vs. deserializing).
  3. Supporting models belonging to different namespaces. Commonly when we have v1 vs vn Models within the same service description space. Throwing this in here since its related and we should think about 2 ☝🏼️holistically with this in mind.
  4. Non json schema model description support (xsd, protobuf)
darrelmiller commented 8 years ago

I'm having a real hard time creating a response to this. Let me start with some low hanging fruit.

@dilipkrish In the example you show, you are not really describing Link Relation Types, instead you are declaring what Link Relation Types might be present in a response. That's a valid piece of information but not quite the same as describing link relation types. Maybe I'm just being pedantic. It has been known to happen :-)

I've always thought OpenAPI would best be able to describe Link Relation Types by defining a notion of OperationClass where the definition can be reused by Operations. But that's an idea for another thread.

@jasonh-n-austin I have two thoughts about this issue.

1) I agree with @dilipkrish 's comment. If you are using a "standard" media type like Hal, C+J, JSON-API, do you really want to have to recreate the Open API definition of those conventions in every API you create. However, it would be nice to be able to point to a globally accessible Open API description of those formats.

2) If you have designed an API that re-uses a set of conventions for many responses across your API, then yes it would be awesome to be able to describe those conventions in a single place and identify them. To be honest, I'm not sure how you would be able to mechanically describe those conventions, but I'd love to see suggestions.

It is interesting to note that this wrapper/model distinction parallels the formats/profiles distinction that the hypermedia folks talk about, and have been talking about for years, without a whole lot of success.

dilipkrish commented 8 years ago

@darrelmiller Want to make sure I understand your comment

In the example you show, you are not really describing Link Relation Types, instead you are declaring what Link Relation Types might be present in a response.

My intent was to do both So, going back to the example above,

        //snip
         - rel: "delete"               
               $urlRef: "#paths/pet" 
               method: "delete"
       //snip

What that is describing is that there is a "delete" link relation; and that it is further described by another swagger operation (#path) within the same document with the endpoint /pet. Now because of the way swagger is modeled, we need to qualify which http method in the description of the /pet operation we need to use. So the idea here was that we could self-host describing the link relationship types. In this case the link relation type is ephemeral and is scoped just for that particular operation and not a standard like the edit link relation type.

Probably a better example would've been to make it concrete like so?

        //snip
         - rel: "delete-pet" //<------    
               $urlRef: "#paths/pet" 
               method: "delete"
       //snip

Hope that makes sense. thoughts?

DavidBiesack commented 8 years ago

I'm keenly interested in describing link relations associated with resources (and their response schema). I think that should be a separate topic, so as to not get side tracked from the OP on wrapper objects.

However, in @dilipkrish last response, link relation "rel" names should be relative to (no pun intended) the resource that contains them, so rather than "delete-pet" to provide a name that may be intended to be unique or namespaced within the API, it should be just "delete" and refer to (be relative to) the resource (path) in which it appears. Links outside of the context would probably be qualified. (Also, any link relation could refer to any other resource/operation). Thus Many individual resources (various paths) would have the same link rel value; the path provides an implicit namespace.

That is, the names of the link relations are defined by the API context, not determined by the (Open API) description/structure and its namespace constraints.

fehguy commented 8 years ago

parent issue #586

kscheirer commented 2 years ago

I am evaluating this as a possible use case for overlays, https://github.com/OAI/Overlay-Specification/discussions/9.

I don't think overlays would be useful here, links are part of openapi3 now and there is also workflow SIG.

handrews commented 9 months ago

This has been solved in OAS 3.1 by using dynamic references to define generic types.