apiaryio / api-blueprint

API Blueprint
https://apiblueprint.org
MIT License
8.63k stars 2.14k forks source link

How do I minimize noise created by collections? #82

Closed danvine closed 9 years ago

danvine commented 10 years ago

From what I'm seeing, the collection model is the most desirable approach.

It looks fine at a small scale, http://docs.thingsapi.apiary.io/?3ColumnDocumentation=1

But it easily gets out of hand and creates tons of visual noise.

Readable vs Noise screen shot 2014-04-22 at 5 21 00 pm

How can achieve the readable version?

zdne commented 10 years ago

@danvine

I am afraid at the moment there is no better solution than breaking it into separate resource groups. But I guess you already have some groups defined and doing so would clutter it as well...

To be frank I am not sure what would be the best solution to this.

I guess one question is whether it would be on the tool' side (Apiary's rendered documentation in this case) where it could somehow heuristically / automagically (?) group related resources into sub-groups (based either on resource names and / or URIs).

Another option would be to extend the API Blueprint syntax to allow some sort of group nesting.

Ideas?

danvine commented 10 years ago

I'll take it however I can get it. :)

a. If Apiary collapsed Foo Collection and Foo when they are encountered in that order, I'd be happy. b. An inline tagging system could be used to group as well as tag resources internal/external. c. Respecting markdown like headers would be natural and allow for this.

How does one go about making option A happen?

BRMatt commented 10 years ago

What about if resource groups were ignored when building the API? I guess that may not always be appropriate. This is what our draft documentation looks like at the moment:

2014ear-04-23_selection

Most readers don't care about the hierarchy of the Plan/Plan collection resource groups, they just care about Retrieving/Updating/Listing/Creating plans. It'd be cool if the navigation could be focused on what the user wants to achieve, rather than how the API is implemented. As an example of this, see the Stripe API docs.

Also, I think you're right that this should probably be implemented in the tool rather than the specification. The blueprint describes the semantics of the API, some of which may not be relevant to the end user (e.g. the state machine discussion in the other ticket. Unfortunately I can't find it right now).

jrep commented 10 years ago

Sounds familiar (#81)

zdne commented 10 years ago

Frankly, I am still not quite sure whether this is really tooling-specific question or we should throw a new API Blueprint syntax on it (e.g. nested groups or some other sort of tagging).

Ideas?

danvine commented 10 years ago

Let me start off by saying I love the potential for this ecosystem.

Guiding the masses towards json+collection, standard use of nouns and verbs will make all of our lives better.

Throw in automated testing, beautiful documentation, mocking, inspection and make it all turn key.. shutup and take my money.

I belive the friction comes from the ridgid syntax. Tightly coupling documentation hierarchy and paths results in excess noise and the feeling my API can't be expressed using these tools. (#81)

Here is a braindump of how I'd decouple the paths and verbs. Since it is similar to the legacy syntax, I'm probably missing part of your new vision.

Payloads ommitted for readability.

# API NAME

## Group Things (This is the doc header)

### Things Collection (subheader)
Creates new thing and put it into collection.

+ GET /things{?filter}
+ Parameters
    + filter (string, optional)
+ Request (application/json)
+ Response 201

### Create New Thing (subheader)
Creates new thing and put it into collection.

+ POST /things
+ Request (application/json)
+ Response 201
+ Response 400

### Retrieve Single Thing (subheader)
Retrieve the whole or filtered things collection.

+ GET /things/{id}
+ Parameters
    + filter (string, optional)
+ Response 200
+ Response 404

### Less than Ideal Action on Thing (subheader)
**In short: Don't unless you have to.**

+ POST /things/{id}/reboot
+ Parameters
    + id (integer, optional) ... The ID
+ Request (application/json)
+ Response 200
+ Response 400

### Other less than Ideal Action on Thing  (subheader)
**In short: Don't unless you have to.**

+ POST /things/{id}/crop
+ Parameters
    + id (integer, optional) ... The ID
+ Response 200
+ Response 400
zdne commented 10 years ago

@danvine

Tightly coupling documentation hierarchy and paths ...

I believe this pinpoints the problem. Idealistically in the case of REST API the paths should be irrelevant as they are mere hyperlinks between resources.

I'm probably missing part of your new vision

The grand picture of thing is to encourage resource oriented architecture while still making RPC / SOA descriptions viable.

For more details on this refer to https://github.com/apiaryio/api-blueprint/issues/13#issuecomment-33506569 and the Resource Blueprint concept.

Now with the respect of your original comment / question I believe this clearly points to a major flaw of a flat structure of the rendered documentation. Should the rendered documentation capture the resource relations (and embedding) in a better way this might not be an issue.

With that being said the syntax (and parser) can definitely go towards this goal and provide some clues to the tools on relationship and embedding of resources...

Thanks for sharing your ideas! Much appreciated.

jrep commented 10 years ago

The notion that "the paths should be irrelevant" is a bit over-worked. Granting all due genuflections to Fielding's dissertation, particularly the un-published half of it that makes him most passionate, there are two aspects on which Fielding, and the notion, make some unexamined assumptions, and limit thereby the applicability of the notion and the diatribe. Unfortunately, Blueprint covers the whole field of one of these aspects (limiting Fielding's diatribe to at most 50% of Blueprint's need), and sadly enough, Blueprint is 100% on the other side of the second aspect, leaving perhaps no scope at all for Blueprint to depend on the "irrelevant paths" notion.

The first aspect is: "who's calling?" The REST APIs of interest are about evenly divided between "human-to-machine" models and "machine-to-machine" (h2m vs. m2m). Fielding's idea of modeling APIs on established hypertext models plants him squarely in the "h2m" camp, but there's no such dependency to Blueprint: it can be and is used extensively for both purposes. This distinction's significance is most apparent when we consider "what comes next?" after any given call. In general, there may be multiple possibilities. The Hypertext archetype solves the conundrum by presenting the possibilities in the form of text strings recognizable by a human, leaving the thinking and choosing to the human. This works well not only for the common, near-universal steps like "Save" and "Cancel" and "Next," but even when the system needs to offer unusual or even unique paths. People are good at this sort of thing, and a decision-time text hint suits their mental process well. But this is not so for m2m APIs. Machine-coded clients, even by-the-grace-of-God AI clients, just aren't up to the task. A human has to be involved, and lacking a run-time human the job devolves to the coding-time human. But wait! That h2m run-time human was benefitting from the clarifying offerings encoded by the coding-time human; to whom can the m2m coding-time human turn for guidance? An important part of that answer is, to the consistency and transparency of the API model: to the URIs, since they're the primary interface available. This means that, in this situation, the clarity, consistency, pattern, and meaning of the URIs is an important part of the API design accessibility; random URIs are fine behind an h2m Hypertext here's-a-string-to-help-you-choose UIs, but they're crippling for the coder trying to guess what might come next.

The second differentiating aspect is the distinction between run-time/execution needs, and coding-time/documentation needs. At run time, the only responsibility of the URI is to guide the request to the code that can fulfill it: to satisfy the click. While at coding time this need is always in view, you can only get there by fulfilling a more immediate need: the URI is part--indeed, the primary part--of the means given the developer for understanding the API as a whole. The URI is, in fact, documentation, and has the same sort of clarity obligations as any other documentation. The moment anyone, even as rhetorical hyperbole, talks about "meaningless," "random," or "opaque" URIs, you know they've left the realm of URI-as-documentation. It is unfortunate, then, to realize that the use of Blueprint is 100% documentation. There is no place, in Blueprint, for opaque URIs. They are no more acceptable here than it would be to write the narrative documentation by choosing letters at random to form your "words". Furthermore, the URIs are the most natural, perhaps the only practical representation of the actual resources (which are, I think we all agree, the heart and point and determinant of a REST API's "RESTfulness"): the only other possibility is the resource structure itself (in, say, JSON or XML), but this is too ponderous for links, Tables of Contents, or descriptive references.

Since, then, meaningful URIs are crucial to the the very meaning and purpose of Blueprint itself, I find it not a little frightening to see you so-glibly reference this so-inappropriate "irrelevant paths" trope. Please reconsider. Please use the power of Blueprint language design to encourage, support, empower, and convey the meanings of the URIs. Not to impede, fracture, and prevent it.

zdne commented 10 years ago

Dear @jrep I am sorry for the misunderstanding and poor choice of words. The URIs are of course not irrelevant.

An URI is integral part of a Resource and as such it must be present and easily available in the resource documentation.

What I have meant is that putting the emphasis on the absolute URI value while designing, building and maintaining a distributed hypermedia system has proven to lead to tightly-coupled implementations. This of course inevitably leads to systems with extremely fragile clients, which in turns complicates any evolution of the API and adds burden on the client developers.

With that being said the aim of API Blueprint as language is to provide a common ground for describing and discussing web APIs regardless of paradigms (and in the future, protocols) they use.

As for the question of original poster – @danvine I believe the solution for reducing the "noise" introduced by the higher number of resources (which they indeed are!) in the TOC section is to improve the rendered documentation's TOC section's layout, which is something we will definitely look it to.

If you feel this is something that should be addressed on the syntax side of API Blueprint I would be happy to discuss any proposal you might have.

Thanks!

zdne commented 9 years ago

Hopefully the concerns in this question will be addressed with other features – namely #88. Closing.