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

Clarity for API Description namespace #1

Merged
merged 13 commits into from
Aug 3, 2015
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update RFC for clarity and structure
  • Loading branch information
smizell committed Jun 18, 2015
commit 39c0c9d9b715eb28945416476980c5d20a2e166e
57 changes: 31 additions & 26 deletions text/0000-clarity-api-description.md
Original file line number Diff line number Diff line change
@@ -8,65 +8,70 @@ Provide clarity and additional elements/properites in API Description namespace.

# Motivation

This will make it easier to understand for new users and cover more areas for existing API Description formats.
The purpose of this document is to make it easier for newcomers to understand the format and build tools around it.

# Detailed design

I have spent a lot of time thinking about this namespace, and I believe I’m going to keep my suggestions for now mostly to making the namespace clearer to new users. I think we can handle adding state and affordances to this later to accommodate things like the concepts from Resource Blueprints.

This contains mostly questions and thoughts. Would love your thoughts on what you'd like to see addressed in a PR.

## Combine Namespaces

I think we should combine the API Description namespace with the resource namespace. Z is already good with this, but listing it here.
We should combine the API Description namespace with the resource namespace.
Right now they are separate and it would be clearer if they were not.
Copy link
Member

Choose a reason for hiding this comment

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

👍


## Elements in Attributes

This is mainly a point for discussion. Refract allows for including elements within the attributes section of an element. Even though it’s possible, would it be helpful to avoid this in such an important namespace? Reason being, this will be one of the first places people interact with Refract, and to use complex features may be too much.
Refract allows for including elements within the attributes section of an element.
Even though it’s possible, it may be helpful to avoid this in such an important namespace.
Reason being, this will be one of the first places people interact with Refract, and to use complex features may be too much.
Copy link
Member

Choose a reason for hiding this comment

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

👎

I do not think this is possible. Especially when it comes to MSON samples / default values – those guys are and should be elements .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.


## HREF Variables

I think we should call them “hrefVariables” everywhere instead of parameters in places. I think this will be more consistent and easier to understand for newcomers. This will make more sense in how we handle inheritance.

Question: does it make sense to provide an “in” attribute that defines where in the URI template the variable may be found (e.g. path, query param, etc.)?
We should call them “hrefVariables” everywhere instead of parameters in places (specifically transitions).
I think this will be more consistent and easier to understand for newcomers.
This will make more sense in how we handle inheritance as well, because parameters inheriting from hrefVariables does not seem optimal.
Copy link
Member

Choose a reason for hiding this comment

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

👌

I am neutral on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This mainly goes to my point of consistency across things like parameters, attributes, and variables. Maybe we could agree on the best way to define these (which could be just to leave as is).


## Defining Classes

Swagger provides a way to define tags that can be applied to resources throughout the document. Refract has the “class” attribute that we can use the same way, we only need a way to define a class name and provide the description for it. Of course, this won’t carry over to API Blueprint, but that’s OK.
Swagger provides a way to define tags that can be applied to resources throughout the document.
Refract has the “class” attribute that we can use the same way, we only need a way to define a class name and provide the description for it.
Of course, this won’t carry over to API Blueprint, but that’s OK.
Copy link
Member

Choose a reason for hiding this comment

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

Not sure what you are prospering here. Create an element that defines classes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Swagger has a tags. Refract has classes. We can use classes, but have to have a way to define these classes used because they have meta data in Swagger.

The other option is to go the tag route and create tag elements, which is fine for me as well.

Copy link
Member

Choose a reason for hiding this comment

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

@smizell Is this a general concept we would like to have in API Refract or is it more or less specific to a particular (swagger) format and as such it could be kept as part of recently proposed metadata perhaps using the adapter class?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think calling them classes will be quite confusing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Paraphrasing from @smizell & the Swagger spec: a resource may include a list of tags as a way of grouping items for tooling authors. These tags can contain a name, description, and external resource link. One resource may have multiple tags.

You can think of this as similar to, but more flexible, than our resource groups. A resource can only be in one resource group. Also, resource groups can create a hierarchy, while tags (as used in Swagger) cannot.

To me this is a generic API description feature. I believe that a flexible way to group resources would be beneficial to the adoption of a generic API description format.

I would propose that we either:

  1. Create a hierarchical tag element for refract that references resources defined elsewhere in the document. Our resource groups would be implemented as this new element and we can support Swagger and other formats that use tags as well. For example:

    element: category
    meta:
    class: ['api']
    content:
    -
      element: category
      meta:
        class: ['resources']
      content:
        -
          element: resource
          meta:
            title: 'Resource 1'
          attributes:
            tags: ['tag1']
          content: ...
        -
          element: resource
          meta:
            title: 'Resource 2'
          attributes:
            tags: ['tag2']
          content: ...
    -
      element: category
      meta:
        class: ['tags']
      content:
        -
          element: tag
          meta:
            title: 'tag1'
            description: 'Some tag description'
          content:
            -
              element: tag
              meta:
                title: 'tag2'
                description: 'I am a nested tag'
            -
              element: externalRef
              content: 'http://example.com/'

    This is really powerful but could present some interesting problems, such as how the heck to render the documentation since a resource may be in multiple tags.

  2. Leave things as-is and add a flat (i.e. non-hierarchical) tag element to support Swagger's use case. Tooling authors will need to support both resource groups and tags, but the tagging system is simplified. I think this is more explicit than re-using the class metadata. So far we have used the class metadata to differentiate the specific type of element (i.e. group of resources vs. group of data structures), not as an arbitrary grouping mechanism. If resources have a unique ID in the document then they should be easy to reference with a tag element.

    element: category
    meta:
    class: ['api']
    content:
    -
    element: category
    meta:
      class: ['resourceGroup']
    content:
      -
        element: resource
        meta:
          id: some-document-unique-identifier
        content: ...
    -
    element: category
    meta:
      class: ['tags']
    content:
      -
        element: tag
        meta:
          title: tag1
          description: I am a tag
          href: http://example.com/
        content: ['#some-document-unique-identifier']

    This will be simpler to implement but maybe less powerful. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@danielgtaylor The first to me seems less "magical," and it also seems more like a Refract way of doing it. But I see you've proposed nested tags. Is that the recommendation for doing this in a generic way?

Copy link
Contributor

Choose a reason for hiding this comment

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

@smizell my thinking here is that if we want to support both generic hierarchical grouping elements (e.g. categories in refract today, which is how we implement API Blueprint resource groups) and allow an item to be in multiple grouping elements (a resource that is a part of two groups aka tags like in Swagger) then a way to support both is by creating a generic hierarchical grouping element that uses references to define its members. Rather than having an element like a resource group which contains resources, we have a tag element that a resource can reference. This allows for really flexible resource organization and should support most formats. For example:

# Ungrouped Resource [/nogroup]

# Group Example Resources
Some description.

## My Resource [/foo]
## Another Resource [/bar]

Would become something like (even a bit simpler than I proposed above since we really don't need the resources or tags classes):

["category", {"class": ["api"]}, {}, [
  ["resource", {"title": "Ungrouped Resource"}, {}, ...],
  ["resource", {"title": "My Resource", "tags": ["Example Resources"]}, {"href": "/foo"}, ...],
  ["resource", {"title": "Another Resource", "tags": ["Example Resources"]}, {"href": "/bar"}, ...],
  ["tag", {"title": "Example Resources", "description": "Some description."}, {}, null]
]]

Of course that assumes we use the tag title as its unique identifier. As a tooling author I can build a menu based on the tags and using Minim we can easily query for all elements tagged with foo:

  • Ungrouped Resource
  • Example Resources
    • My Resource
    • Another Resource

Does that make sense? What do you think? This is somewhat future-proof as it allows arbitrarily nested levels of groupings and resources for organization while keeping the refract representation simple(-ish). It can also be extended in the future by adding a class to the tag element, for example to create a dataStructure-only tag or something along those lines. Any thoughts on this @zdne?

Copy link
Contributor

Choose a reason for hiding this comment

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

I really like the idea in the above comment but I am worried about how documentation will render it if lots of resources from a resource group is mixed with data structures in between and resources from other resource groups. I guess we need to flesh out the example once to see if it's okay or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course that assumes we use the tag title as its unique identifier.

I kind of struggle with this. On one hand, it makes sense because we would have to come with a unique ID for each tag. On the other hand, I get a funny feeling tying it to the human-readable title. I don't really feel strongly either way here.

I'm also a little iffy on having both category and tag in the spec. Seems like people have mental maps to what these are, and it would take some work to get your mind around the differences IMO. In other words, a resource can be in one and only one category, though it can be in many tags. (This is ignoring the fact the user could reference a resource with ref, so maybe I'm making a false assumption)

But I do really like this direction, and it seems like a necessity. We could leave this for a future change to the namespace so we can work this out more. @danielgtaylor @pksunkara

Copy link
Member

Choose a reason for hiding this comment

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

❔ So is there any consensus on this? Leave category element for now and think about introducting "tags" in a future? Ideas @kylef ?


## Clarify Inheritance
Copy link
Member

Choose a reason for hiding this comment

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

I guess this is not really about inheritance (as in MSON). Are you talking about guidelines how to resolve or interpret some elements (hierarchy)? I do not understand any point bellow – maybe an very brief example would help?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, maybe better put as how to interpret certain values that are defined on parent elements. This is proposing we explicitly define those in the spec.

Copy link
Member

Choose a reason for hiding this comment

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

how to interpret certain values that are defined on parent elements

👍

Copy link
Member

Choose a reason for hiding this comment

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

👍 for this.

One note, tools such as swagger2blueprint should output when information is lost so the user knows what happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

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


We need to clarify how inheritance works with:
We need to clarify how inheritance works by defining the behavior for:

* HREF Variables and HREF values throughout the document
* Content types in payloads
* Methods in transitions
* Resources with schemas (though not in the spec) should be inherited by transitions

I don’t so much mind the inheritance rules, as we can handle this kind of inheritance with Minim by traversing the tree up and down for the correct HREF.

## Transitions at Root

We should be able to define transitions on the root of the document and not require they are nested within a resource. This type of transition, though, should have a URL and a method.
We should be able to define transitions on the root of the document and not require they are nested within a resource.
Copy link
Member

Choose a reason for hiding this comment

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

👍

Copy link
Member

Choose a reason for hiding this comment

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

Surely they are just transitions on the "root resource", i.e, with href of /?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure we can assume the URL (or resource) this transition belongs to. To me, it almost feels like shorthand for a resource with an HREF and a transition inheriting that HREF.

Copy link
Member

Choose a reason for hiding this comment

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

I'd say this can be introduced later as a non-breaking change.

This type of transition, though, should have a URL and a method.

## Transition Attributes
## Subclass Asset

I think it would be helpful to call this something other than attributes, as this will not be obvious to most people. Additionally, it means you have “element.attributes.attributes”, which is not a big deal, but something I think we can avoid. Not sure what to call it.
We should subclass the Asset Element and add one called “messageShema” and another called “messageBody.”
Copy link
Member

Choose a reason for hiding this comment

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

Typo: messageShema

This will make reading a API Description make more sense than seeing Asset alone with classes.
Copy link
Member

Choose a reason for hiding this comment

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

👌

I am somewhat neutral on this one. I can imagine other assets that are neither. But OK to proceed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can also define when it is recommended to create a new element vs. using a class. This definition today seems to make sense:

  • Create an element if it adds new metadata, attributes, or content.
  • Otherwise, create a class if it adds nothing new but needs clarification on the type (e.g. generic grouping element category vs. a specific group of resources).

By that definition I do not believe that messageSchema or messageBody add anything so they should remain classes. I am open to changing the definition though 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm good with using these definitions and leaving it as classes.


This seems to me like a data structure for the transition.
## Provided Media Types

## Subclass Asset
We should add a section that defines what media types the server will respond with.
Copy link
Member

Choose a reason for hiding this comment

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

👌

Isn't this duplicating the information? I guess I am failing to see a benefit of this. Is this the default media types for all requests / responses unless the request / response states otherwise?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is what the server MAY respond with. It is a list of hints at what the server provides, though the transactions may never show some of them.

Swagger has a property called produces that allows you to specify an array of available media types.

In reading over the Swagger spec again, I see that you can specify this produces on the API level. We do not have an API element to accommodate this, only category. This is a side question: should we have an api element for specifying this kind of API metadata?

Copy link
Member

Choose a reason for hiding this comment

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

Again, as above, the question is whether this is useful concept for any API (description / adapter) and thus it should be "canonical" or is it specific to Swagger format and hence it should be adapter metadata..

Copy link
Contributor

Choose a reason for hiding this comment

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

...the question is whether this is useful concept for any API (description / adapter) and thus it should be "canonical" or is it specific to Swagger format

Another question: would something like this be valid and useful?

# My resource [/frobs/{id}{?description}]
+ Attributes
  + id (required)
  + description
## Get a frob [GET]
+ Parameters
  + id (required)
+ Response 200 (application/json)
+ Response 200 (application/yaml)
+ Response 200 (application/xml)
+ Response 200 (text/plain)
## Update a frob [PUT]
+ Parameters
  + id (required)
  + description
+ Request ...
+ Response 200 (application/json)
+ Response 200 (application/yaml)
+ Response 200 (application/xml)
+ Response 200 (text/plain)
...

The basic question to ask here I think is whether the request/response examples are expected to be an exhaustive list of all possible returned mimetypes or if that information makes more sense at the root level of the API description document. I think it only makes sense at the root if the responses can be generated, e.g. from something like MSON with default values. Otherwise we have a documented & supported response mimetype with no usable example, and this is not specific to API Blueprint or Swagger.

Copy link
Member

Choose a reason for hiding this comment

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

I think this is somewhat linked to #1 (diff), you could describe a class which states that various media types are supported.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes sense to me. Do you think we can address this by allowing for specifying media types as listed in this RFC? Do we need to do more?


I think it would be clearer if we subclass the Asset Element and added one called “messageShema” and another called “messageBody.” I think this will make reading a API Description make more sense than seeing Asset alone with classes.
## Add Schema to Resource

## Category Element
A resource should be able to have its own schema, whereas now it cannot.
Copy link
Member

Choose a reason for hiding this comment

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

👎

I am somewhat against this if it is just one schema. Because having a schema implies the serialization format. Another thing would be if a resource could have multiple assets associated and some of them could be schemas. That would be 👍 for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another thing would be if a resource could have multiple assets associated and some of them could be schemas

Sounds great.

Basically, it allows for using the Resource Model. Swagger offers simply a way to define the body schema for an entire resource, so this would cover it as well.

Copy link
Member

Choose a reason for hiding this comment

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

❗ I would like to deprecate and remove the Resource Model from API Blueprint completely so I would not build anything around this per se.

Copy link
Contributor

Choose a reason for hiding this comment

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

In my mind, I consider the MSON under the attributes section of a resource to be it's schema.

Copy link
Member

Choose a reason for hiding this comment

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

For me to get pass this is either:

  1. Do not introduce schemas for resources just yet (can be non-breaking later)
  2. Introduce multiple schemas per resources (but do we really need it right now)


I still have trouble understanding what “category” means here, but that may just be me. Is there a better name? Is this from the philosophical world? Maybe something like “section” or from the HTML world “div”?
# Unresolved questions

## Provided Media Types
## Category Element

Swagger supports a section that defines what formats the server will respond with. This should be added (already discussed with Z).
What is a "category"?
Does this word make sense used here?
Maybe something like “section” or from the HTML world “div”?
Copy link
Member

Choose a reason for hiding this comment

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

"Category" is a general grouping element. I am against "div" (HTML) or "group" and "section" (ambiguity with API Blueprint specification).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To rephrase: what does "category" mean?

In the modern world, I see the term category used to provide additional meta data for some object, though I suppose traditionally it has meant as a way of grouping things. I'm fine leaving it, but it did take me a bit to understand what you meant by it.

Copy link
Member

Choose a reason for hiding this comment

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

Interestingly I've thought the first time I've heard the term was from you or Mark. Anyway, I am easy on settling on any other word if needed (but from those proposed I like category the best).

Copy link
Contributor

Choose a reason for hiding this comment

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

There are a few usable choices but I'm not sure what was originally proposed. I'll agree that as an American English speaker the term category is a little awkward at first. I much prefer group or collection. Question: why does ambiguity with the API Blueprint spec pose an issue for Refract if the concepts are essentially the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Per @danielgtaylor's comment, we have:

  • Category
  • Group
  • Collection

Which sounds best for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

I like category. If it's not possible, I would go with collection.

Copy link
Member

Choose a reason for hiding this comment

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

All of the words are equally bad in my opinion so I do not have any clear winner. Anything is 👌 (collection has a different meaning when it comes to resources)


## Add Schema to Resource
## Transition Attributes

Should resources be able to have their own schema (currently Asset with `messageBodySchema` as class).
I think it would be helpful to call this something other than attributes, as this will not be obvious to most people.
We have parameters, variables, and attributes throughout the document, which seems confusing.
What should this be called?
Copy link
Member

Choose a reason for hiding this comment

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

So you want to get rid of parameters (in favor of hrefVariables). Given a transition is function its parameters are well, parameters. In representor we also use the term input properties.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The URI Template RFC refers to them as "variables". I am more so interested in having consistency, and I'm still wondering why they are called parameters.

Given a transition is function its parameters are well, parameters. In representor we also use the term input properties.

A URI template is instructions for how to build a request. It is more close to the concept of a form than a function, though when you implement you may implement as a function. Either way, they are instructions.


But this point is saying that there is this other term used for transition attributes. This maybe should have been part of the unresolved questions area, but having parameters, variables, attributes, and data structures that are all simply MSON objects feels like we're missing something. I am not sure I have a proposal, but this seems like it could be quite confusing.

Copy link
Member

Choose a reason for hiding this comment

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

The URI Template RFC refers to them as "variables".

First, that RFC has many problems 🎢 they call anything its value can vary in the template a "variable". However that does not say anything about what is the purpose – the use – of the variable. Is it a path segment or query parameter etc. Something can be hinted by operators. But I would definitely refrain from being inspired by RFC 6570. When it comes to names I would stick with URI RFC names instead.

However without a concrete proposal I have not much to comment here.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 I agree. Calling them attributes is quite confusing with refract's attributes. I generally say body params when I am explaining it to other users.

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW, this is also problematic for implementers that provide an element.attributes and want to expose shortcut properties. In Fury this is a bit awkward:

// Long version
console.log(element.attributes.get('attributes'));

// Short version
console.log(element.attr);

If/when a Python or Ruby implementation happens we'll need to deal with the inevitable name collisions as well. If we could at least try to stay away from reusing these names that would be appreciated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are multiple contexts for this. I am good with data for describing the body of the transaction. What do you call URI template parameters? I think it would be good to sync these up throughout.

Copy link
Member

Choose a reason for hiding this comment

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

Is this considering the Hypermedia Project charter and representor naming in any way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe we called them attributes when part of a resource. In regards to the URI template, looks like we bounce back and forth between attributes and parameters.

I've also looked online in several places and do not see any consistency. Here they say things like query parameters and query string variables in the same article. I've seen this elsewhere. So I don't feel like we can go wrong.

So if we sync up with the Hypermedia Project, we use attributes for the body of a request/response. With regards to URI template, Wikipedia says parameters. Does that solve it? :)

Copy link
Member

Choose a reason for hiding this comment

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

@smizell So the conclusion, we leave it as parameters and attributes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kylef Well, after thinking this weekend, I'm not entirely sure. In the Hypermedia Project, we call part of the payload attributes... not the entire payload. So data really may be better as it in encompasses attributes and anything else, such as transitions.