Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Traits #47

Closed
zdne opened this issue Dec 17, 2013 · 49 comments
Closed

Traits #47

zdne opened this issue Dec 17, 2013 · 49 comments

Comments

@zdne
Copy link
Contributor

zdne commented Dec 17, 2013

Introducing the API Blueprint Object Trait. Addressing following milestones:

Full implementation of traits assume following issues are implemented:

What is a Trait

Trait is a quality or characteristic of an API Blueprint object (hereafter just object). At the moment the following sections of API Blueprint are recognized as API Blueprint object:

  • API
  • Resource Group
  • Resource
  • Resource Model
  • Action
  • Request
  • Response
  • Parameter

Traits can be used add additional semantics or a set of characteristics to an object.

Semantic Trait

A semantic traits adds a semantic meaning to an object.

Definition of a semantic trait:

# My API
+ Trait A ... Object Quality "A"

Referencing a defined trait:

## Resource 1 [/1]
+ Traits
    + [A][]

In-place definition & use of a semantic trait:

## Resource 1 [/1]
+ Traits
    + A ... Object Quality "A"

NOTE: Traits defined in-place cannot be referenced later

An object can reference multiple traits:

## Resource 1 [/1]
+ Traits
    + [A][]
    + [B][]
    + C ... Object Quality "C"
    + Type = `safe`

Characteristic Trait

In addition to its semantic meaning a trait can also express certain characteristic of object's payload(s).

Where payload characteristic is one of:

  • parameter characteristic
  • property characteristic (new in Format 1B)
  • [request | response] header characteristic
  • body characteristic
  • schema characteristic

For example:

# My API
+ Trait Color
    + Response Headers
        + X-Resource-Color (string, `red`) ... Color of the resource.

## Resource 1 [/1]
+ Traits
    + [Color][]

One trait can also represent a set of object characteristics:

# My API
+ Trait Art
    + Headers
        + X-Resource-Color (optional, string, `red`) ... Color of the resource

    + Properties
        + size = `42` (number) ... The size of an object

## Resource 1 [/1]
+ Traits
    + [Art][]

For more examples see https://gist.github.com/zdne/01e287fe18d232672d43

@jrep
Copy link

jrep commented Dec 17, 2013

Does this proposal enable me to apply a Trait to all APIs in some collection (say a Group, or even the whole blueprint)? That is, I want to make one declaration affect many APIs. Maybe like:

# My API
It's cool!
## Group Pickles
+ Trait Color Green
### Resource /dill
...
### Resource /gherkin
...
## Group Apples
+ Trait Color Red
### Resource /gravenstein
...
### Resource /rome

and have dills and gherkins both be Color Green, while gravensteins and romes would both be Color Red

It appears I could write blueprint like that, but it's not clear to me that it would have the meaning I want.

@zdne
Copy link
Contributor Author

zdne commented Dec 17, 2013

@jrep

Yes that is the idea.

Let's say you would have some sort of authentication trait defined like this:

# My API
+ Trait Auth
    + Request Headers
        + access_token (string, `00000000DEADBEEF`) ... Authentication token

And then two groups defined like this:

# Group Secured Access
+ Traits
    + [Auth][]

## Resource 1 [/1]
...

# Group Open Access

## Resource 2 [/2]
...

All HTTP request messages sent to resources defined in the Secured Access group are expected to contain the access_token header while those sent to the Open Access group not.

You can go really crazy with this and imply pretty much any characteristic of underlying payloads like its schema.

With that being said some combination would probably not make a whole lot sense which is also the challenge of this concept. I want to bounce this idea with anyone who is interested. This proposal is open but yet I would love to freeze it in a week or so, so I can start working on its implementation.

@jrep
Copy link

jrep commented Dec 18, 2013

Any interaction with Modularity (issue #8) or External Assets (issue #20) (looking for something roughly like C's #include)? That is, I could really use the ability to define some Traits in a shared file, suck that file into the main Blueprint, and incorporate Traits by reference? Restrictions on the location within the Blueprint of the Trait definition?

@zdne
Copy link
Contributor Author

zdne commented Dec 18, 2013

@jrep not directly. I was totally the same way. However the #8 & #20 will have to wait until the parser harness - Drafter apiaryio/snowcrash#57

As for the location of where a trait can be defined - I haven't decided yet. Originally I was thinking about leaving it for the top level section (API) of a blueprint only. But perhaps it makes sense for the group section as well. We can always extend this scope. The only reason I do not want to allow it everywhere is a possible pollution of the "symbol" space - maybe then we would need some better form of addressing symbols to prevent ambiguity...

Also I am not sure whether there is a clear difference between a trait definition and its use.

Definition of a trait:

+ Trait A ... Object Quality "A"

Definition & use of a trait:

+ Traits
    + A ... Object Quality "A"

Use of a trait:

+ Traits
    + [A][]

Is it distinctive enough?

@BRMatt
Copy link

BRMatt commented Dec 18, 2013

In the multiple traits example the format of the last reference doesn't seem to be described anywhere:

    + Type = `safe`

Is this another method of inline definition?

@zdne
Copy link
Contributor Author

zdne commented Dec 18, 2013

@BRMatt

Good point. I am borrowing from the current parameters syntax.

The whole syntax of a trait (and underlaying characteristics) is based on an concept of a parameterized key:

+ <key name> [= `<default value>`] [([required | optional ], [<type>], [`<example value>`])] [... <description>]

    [<additional description>]

    [+ Values
        + `<enumeration element 1>` 
        + `<enumeration element 2>`
        ...
        + `<enumeration element N>`]  

So both + A ... Object Quality "A" and + Type = safe match the same pattern.

@BRMatt
Copy link

BRMatt commented Dec 19, 2013

Ah gotcha. The only nitpicking thing I'd say is that using that grammar Object Quality "A" would be interpreted as the default value, and Type = safe`` would be the description. Maybe semantics should require a key, e.g. `Object Quality = "A"`? It doesn't really make sense to give a trait name when defining inline.

@fosdev
Copy link

fosdev commented Dec 19, 2013

NOTE: Traits defined in-place cannot be referenced later

What is the reason for this? Maybe I am not understanding what you mean by defined in place. I am assuming you mean a list of traits under a Trait tag. Are you saying the individual traits cannot be referenced or the group or something else?

Seems to me that grouped traits would be useful and a convention of overriding them:

Traits G
+ A something
+ B something else

Traits [G][]
+ B overridden
+ C something new

The latter being the same as:

Traits
+ A something
+ B overridden
+ C something new

Are these purely metadata in the blueprint or do these roll over to the human readable documentation? If the latter, can you selectively show them there or not?

@zdne
Copy link
Contributor Author

zdne commented Dec 19, 2013

@BRMatt

Not sure what you mean by

grammar Object Quality "A" would be interpreted as the default value

In this case the Object Quality "A" is just a mere markdown-formatted discussion. It does not affect anything but the trait's description.

I really think about the name of a trait as a label or a tag if you will. Maybe I am just overcomplicating it and the tag without additional description & value would suffice. E.g.:

+ Trait <trait name A>
    + Request Headers
        + access_token (string, `00000000DEADBEEF`) ... Authentication token

+ Traits 
    + [<trait name A>][]
    + <trait name B>

@BRMatt
Copy link

BRMatt commented Dec 19, 2013

Sorry, I wrote it the wrong way round. So A ... Object Quality "A" is a reference to a trait, and Object Quality "A" is just an added description of the trait? This seems a little unnecessary, presumably the trait has a descriptive name, and could also have a description where it was specified.

+ Traits 
    + [<trait name A>][]
    + <trait name B>

Shouldn't trait B be wrapped in [][]?

@zdne
Copy link
Contributor Author

zdne commented Dec 19, 2013

@BRMatt

Shouldn't trait B be wrapped in [][]?

B is not wrapped in [][] because it is defined in place. Thinking about it I should really simplify it.

Consider:

# My API

A trait defined but not applied to My API:

+ Trait Red

## Resource 1 [/1]

Applying traits to "Resource 1". Referencing previously defined trait "Red", in place defining a new trait "Blue":

+ Traits
    + [Red][]
    + Blue

Is this OK or confusing?

@zdne
Copy link
Contributor Author

zdne commented Dec 19, 2013

@BRMatt @fosdev

I have prepared a hopefully more solid draft of the specification: https://gist.github.com/zdne/01e287fe18d232672d43#file-2-formal-definition-md omitting the extra values and parameters from the trait.

Please let me know whether it is clear enough. I would love to simplify it even further. What I am struggling with is the way to differentiate enough between defining a trait and inheriting a trait (trait <name> vs traits).

NOTE: The rest of the linked gist has not been yet updated to reflect Formal Definition.md.

@zdne
Copy link
Contributor Author

zdne commented Dec 19, 2013

@fosdev

Are these purely metadata in the blueprint or do these roll over to the human readable documentation? If the latter, can you selectively show them there or not?

Good question. Depending on the use case but, personally, I would show the in human readable documentation on-demand (e.g. folded by default).

@BRMatt
Copy link

BRMatt commented Dec 19, 2013

Ok that makes sense now that you've explained it, I guess what confused me was that "Blue" doesn't define any semantics or characteristics, so it's not clear why it's included. Will the trait labels be included in the generated json?

@zdne
Copy link
Contributor Author

zdne commented Dec 19, 2013

@BRMatt

In this case "Blue" really serves as a tag that has hopefully some semantical meaning for somebody else. Indeed those will be included in the AST and its serialization.

Also in the case of plain label / tag such as "Red" there is not much point in referencing it later since writing it over and over is actually simpler. It is only when you start to add to the trait definition when it pays off.

@jrep
Copy link

jrep commented Dec 19, 2013

As to location of the definition: I definitely want it to be possible at top level; you seem to agree. I also have pretty clear, but non-crucial, user story for additional or conflicting definitions at group level. For example, consider an API where all groups require "authentication," but some require one sort (say OAuth) while others require a different sort (say proprietary). One could define both Traits at top-level, giving them different names, but this could place the variant definition very far from its use, which might be awkward both for editing and for reading.

On the visual distinction between definition and use of a trait: I think your examples are clear enough for an experienced Markdown (or Blueprint) reader. That should be good enough, and is consistent with the rest of the standard. It is a little sparse (I understand your hesitation), and indeed I have found the Markdown "empty reference" syntax

+ [A][]

a bit difficult to teach to new users (which I'm doing a lot of), but not fatal.

@zdne
Copy link
Contributor Author

zdne commented Dec 20, 2013

@jrep

this could place the variant definition very far from its use, which might be awkward both for editing and for reading.

Agree. The definition of a trait - a trait definition section will be allowed everywhere where you can inherit a trait.

I think your examples are clear enough for an experienced Markdown (or Blueprint) reader

Fair point. I would love to make API Blueprint more friendly towards new users too. Please let me know should you think of something.

@randysecrist
Copy link

+1 for Traits and making OAuth & Scope definitions easier to add to a large API. Any idea when 1B will rollout?

@jrep
Copy link

jrep commented Jan 31, 2014

This ticket combines or references several things that I really want, and schedules them all, collectively, for FORMAT 1B. That would be sweet; is it realistic? Should I marshall some "relative priority" insights, in case of feature scale-back?

@zdne
Copy link
Contributor Author

zdne commented Feb 3, 2014

Good point @jrep

The implementation of this in Snow Crash issue would surely take some nontrivial time. There will be some "partial" releases on the implementation branch of the Snow Crash.

Surely there are some issues that has to be addressed first before we can start work on the others.

The In-place Semantic Trait implementation might very well be the first one to go. Followed by referencing.

Before Characteristic Traits can be implemented the #25 Message-body Parameters Description #26 Parametric Headers Description and #28 Nested Parameters need to be in place.

I guess this order is pretty much given. What can be discussed is whether implement Message-body Parameters Description or Semantic Traits first.

Also when implementing Characteristic Traits what characteristics should be implemented first?

Opinions or wishes?

@andrewelkins
Copy link
Contributor

👍 Here as well. Found this issue and thought I had my solution to an issue of Copy and pasting, but not so fast. Happy to test.

@andrewelkins
Copy link
Contributor

Any chance there's a PoC getting ready to be pushed to a branch. I'd happily test it out, add to, etc

@zdne
Copy link
Contributor Author

zdne commented Oct 29, 2014

Found this issue and thought I had my solution to an issue of Copy and pasting, but not so fast

@andrewelkins can you please be more specific on what the issue was? Thanks

@andrewelkins
Copy link
Contributor

Sure,

I needed to use the same set of url parameters in several of the end points. So I was hoping to use a trait to do this.

The use case is an event log. So

api/v1/event/1?param1=test&param2=test2
api/v1/event/2?param1=test&param2=test2
api/v1/event/3?param1=test&param2=test2

Etc

@bmironer
Copy link

Hello.
Is there any ETA on this? Or a beta branch we could check out in the meantime. The traits and partial referencing would help us tremendously, provided dredd can make use of it too.

Thanks a lot for the terrific tools.

@dbryand
Copy link

dbryand commented Nov 25, 2014

How are people currently solving the problem of having an Authorization request header, for example, on every single Resource in the API? Duplicating it everywhere?

@DataGreed
Copy link

@dbryand I duplicate it :(

@dbryand
Copy link

dbryand commented Nov 26, 2014

@DataGreed I figured that would be the answer after researching a bit more and reading the issues. I spent last night hacking together a solution that will work for me for the time being. I'm using lodash templating to preprocess my Blueprint file before passing it on for rendering with Aglio and testing with Dredd.

Here is a quick overview of how it works:
image

It's by no means perfect, but keeps me moving forward and allows me to leverage the strengths of API Blueprint and stay DRY.

@itsjamie
Copy link

For those who come and read this, I'm about to test, but I think you could solve the issue of needing to duplicate it by using a tool such as https://github.com/jamesramsay/hercule

@andrewelkins
Copy link
Contributor

That looks excellent

On Tue, Mar 24, 2015 at 6:05 PM, Jamie Stackhouse notifications@github.com
wrote:

For those who come and read this, I'm about to test, but I think you could
solve the issue of needing to duplicate it by using a tool such as
https://github.com/jamesramsay/hercule


Reply to this email directly or view it on GitHub
#47 (comment)
.

@itsjamie
Copy link

I'm hoping Traits becomes a slightly more supported version inside Blueprint. I believe this spec above that's being outlined means I could define a Trait that outlines all the various sub-aspects of a resource. Meaning, I could say that a resource has the Trait "Protected" which means that a access_token is required, one possible response from the resource is now a 401 Unauthorized.. etc...

@zdne
Copy link
Contributor Author

zdne commented Mar 27, 2015

Hey @itsjamie we are preparing a dedicated support for authentication. As soon as we will roll out #25 I will update this and #11 accordingly

@wyattjoh
Copy link

Any update on the progress on this? Our team uses api-blueprint exclusively for our documenting needs. We also have developed several code generators based on it, and could really use support for Traits (specifically, for scopes, which requires Traits).

@zdne
Copy link
Contributor Author

zdne commented May 27, 2015

@wyattjoh the support for authentication scopes is coming soon, I will share an update on this as soon as we will be done with the proposal. cc @pksunkara

@XiaoxiaoLi
Copy link

Any updates on this? This is really useful! Thanks!

@DataGreed
Copy link

With all respect guys, the project seems to be dead or very slow moving, i've switched to RAML.

@pksunkara
Copy link
Contributor

@DataGreed Have you looked at the latest feature we are working on called MSON? You can use it do a lot of things as shown in here, here and here.

It is currently in beta and we are working hard on releasing it completely so that we can use it at a lot of other places in the Blueprint.

@netmikey
Copy link

netmikey commented Dec 9, 2015

What's going on, guys? "Working on it" for 2 years and then "status (6): Cancelled"? Ppl seem to really like api-blueprint but right now, it looks like a dying project - please tell me I'm wrong!

@pksunkara
Copy link
Contributor

Hey @netmikey, This is going to be superseded by MSON which is much much better. @zdne will give a full update soon.

@netmikey
Copy link

netmikey commented Dec 9, 2015

That was the piece of info missing on this issue thread ;) Thanks @pksunkara !

@zdne
Copy link
Contributor Author

zdne commented Dec 10, 2015

@netmikey it is not dying it all! Actually blueprint is doing better than ever. Spoiler: We have a big announcement coming next week and in the weeks to follow. It is just this issue is not going to happen as proposed here, but there are / will be features to address this functionality.

@zdne
Copy link
Contributor Author

zdne commented Dec 18, 2015

As hinted before the some of the features proposed in this issue were already implemented and released ( #25 ) some other are in making ( #11 and #286 ).

Please see the recently published API Blueprint roadmap for the planned features. Check this blog post for more detailed explanation of where the API Blueprint is heading.

Thank you!

@zdne zdne closed this as completed Dec 18, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests