reverb / swagger-spec

This fork of the swagger-spec is intended for 2.0 planning
Other
19 stars 15 forks source link

Lost Resource Description #106

Closed webron closed 10 years ago

webron commented 10 years ago

We've lost a feature from 1.2.

In the api-docs for each resource, you were able to add a description. Since there are no resources in 2.0, you can't add a description to the resource as they appear in the UI.

Compare http://petstore.swagger.wordnik.com/ to http://petstore.swagger.wordnik.com/ui/ and you'll see that each resource in the older version there's a brief description.

The only way I can think of to solve it is by adding a 'tags' property at the Swagger Object, and allow attaching a description per tag. We may even want to have the externalDoc property there.

We can't add description to the pathItem since the UI doesn't treat them as first class citizens.

Unlike the ordering, I don't think this is a display issue only as it adds information on the service, and it can't be solved with vendor extensions since there's no level of resource or tags.

Of course, feel free to use any other solution.

fehguy commented 10 years ago

@webron, good catch. I have to agree that adding something like such:

{
  "tags": [
    {
      "pet": "Operations about Pets"
    },
    {
      "store": "Operations about Purchases"
    },
    {
      "user": "Operations about Users"
    }
  ]
}

In the swagger object makes sense. Being an array, that would also let the user set the order.

This is sort of late in the game but I think important, and importantly--Optional.

webron commented 10 years ago

You don't want to add additional extension points for documentation? Like externalDoc or even vendor extensions? I think it would be good for general-purpose documentation. So you'll have:

{
  "tags": [
    {
      "pet": "Operations about Pets",
      "externalDoc" : "http://foo.com/mydoc.html",
      "x-foo" : "bar"
    },
    {
      "store": "Operations about Purchases"
    },
    {
      "user": "Operations about Users"
    }
  ]
}

If not, then the format should be simplified to:

{
  "tags" :  {
     "pet": "Operations about Pets",
     "store": "Operations about Purchases",
     "user": "Operations about Users"
  }
}

I thought we already agreed that ordering is not part of the scope. And since it is optional, if there's a missing tag, the ordering is left up to the tool? I believe we should be consistent - either we allow ordering or we don't. As long as it doesn't affect the API execution, it should not be part of the spec (at least in this version). Come to think of it, even in the first extended example above, it should probably move to:

{
  "tags" :  {
     "pet" :  {
        "description": "Operations about Pets",
        "externalDoc" : "http://foo.com/mydoc.html",
        "x-foo" : "bar"
    },
   ...
  }
}

And yes, it should definitely be optional. That means no validation should be done if a tag is being used by an operation that it is also 'declared' at the swagger object.

pkedy commented 10 years ago

I'd really like to see this supported. I wrote some conversion code here that preserves the resourceListings.apis in "x-resources" like the snippet below.

"x-resources": [
    {
        "path": "/pet",
        "description": "Operations about pets"
    },
    {
        "path": "/user",
        "description": "Operations about user"
    },
    {
        "path": "/store",
        "description": "Operations about store"
    }
]

This gives me a description from 1.2 but what would really be nice is something like this.

resources {
    Pet : {
        summary : "Operations about pets"
        description : "Longer description in markdown",
        groups : {
            collection : {
                name : "Pets Collection",
                description : "Pets related resources of the Pets API",
            },
            entity : {
                name : "Pet",
                description : "A single Pet object with all its details"
            },
            actions : {
                name : "Pet Actions",
                description : "Extended actions that can taken on a Pet"
            }
        }
    },
    User : {
        summary : "Operations about users"
        description : "Longer description in markdown"
    },
    Store : {
        summary : "Operations about store"
        description : "Longer description in markdown"
    }
},
paths : {
    "/pet": {
        "post": {
            "summary": "Add a new pet to the store",
            labels : {
                resource : "Pet",
                group : "Pets Collection" // or "collection" to point to extended description above.
            }
            ...
        }
    }
}

I choose the term "labels" instead of "tags" but that's just personal preference. Tags usually are just simple strings. Anyway, changing the tags/label into key/value pairs would allow grouping things nicely by resource and scope or otherwise. Not trying to propose a lot of complexity but I think this would be extremely valuable. Currently, I am deriving this information from the path or tags[0] which just doesn't seem very elegant.

fehguy commented 10 years ago

thanks all. Tags are an organizing principle so allowing order should be supported. That means using an array or adding a positional operator. I'd suggest an array.

Adding vendor extensions and externalDocs makes sense as well.

webron commented 10 years ago

Under tags you defined the tag name to start with a slash. Any reason for that? There's no such restriction when adding a tag to an operation.

fehguy commented 10 years ago

That's an error

webron commented 10 years ago

Since you've reopened it, I'd like to suggest a modified version with the array structure (and yes, I know it's based on my original suggestion). There's no benefit to use the "name":"description" mapping. Everywhere else that we used the "name":value mapping, the mapping was an object and not a string. For consistency, the structure should be one of two:

Either like the parameters array structure:

{
  "tags": [
    {
      "name": "pet",
      "description": "Operations about Pets",
      "externalDoc" : "http://foo.com/mydoc.html",
      "x-foo" : "bar"
    },
    {
      "name": "store",
      "description": "Operations about Purchases"
    },
    {
      "name": "user",
      "description": "Operations about Users"
    }
  ]
}

or like the responses structure:

{
  "tags": [
    {
      "pet": {
        "description": "Operations about Pets",
        "externalDoc" : "http://foo.com/mydoc.html",
        "x-foo" : "bar"
      }
    },
    {
      "store": {
        "description": "Operations about Purchases"
      }
    },
    {
      "user": {
        "description": "Operations about Users"
      }
    }
  ]
}

I prefer the first option as the second seems to over-use objects just to support the ordering in the array.

webron commented 10 years ago

Forgot to mention, another advantage of either structure is that the current schema allows you to define several name-description pairs in a single object.

webron commented 10 years ago

A minor fix to the example above, since externalDocs is an object.

{
  "tags": [
    {
      "name": "pet",
      "description": "Operations about Pets",
      "externalDocs" : {
          "description": "some more info about this tag.",
          "url": "http://foo.com/mydoc.html"
      },
      "x-foo" : "bar"
    },
    {
      "name": "store",
      "description": "Operations about Purchases"
    },
    {
      "name": "user",
      "description": "Operations about Users"
    }
  ]
}
webron commented 10 years ago

The specification documentation is proper now. Need to modify the schema. https://github.com/wordnik/swagger-spec/issues/120