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

Embedded Assets #29

Closed
zdne opened this issue Oct 2, 2013 · 13 comments
Closed

Embedded Assets #29

zdne opened this issue Oct 2, 2013 · 13 comments

Comments

@zdne
Copy link
Contributor

zdne commented Oct 2, 2013

Provide a facility to embed an asset inside another asset while keeping the actual asset media-type opaque. For example re-use a message-body asset inside another message-body (e.g. an item inside its collection).

Possibly related issues:

@codebutler
Copy link

Example use cases:

GET /users/1

{"name":"Bob", "email":"bob@example.com"}

GET /posts/1

{"title": "Hello World", "author":/* user 1 */}

GET /users/

[
  /* user 1*/,
  /* user 2*/
]

It would be nice if forward-references were supported too, so documentation for listing all models could appear above documentation to get a specific model.

@zdne
Copy link
Contributor Author

zdne commented Oct 2, 2013

If possible I would love to have opaque assets. By that I mean an asset (a pice of data e.g. a JSON file) that is opaque to the API Blueprint (and its parser). The main reason is that by violating this rule we would need to introduce a media-type specific escaping of asset references.

However to address this issue I was thinking about two possible, not necessary related, ways:

  1. Provide a parser-harness that will be used generate data dictionaries (Data Dictionaries #9) to be referenced (Referenced Payloads #19) later in within a blueprint file

    Basically a script that pre-generates media-type specific data dictionary files and its assets can be later represented like so:

    [asset.one][]
    [asset.many][]
    [asset.ten][]
    
  2. Utilize media-type agnostic parametric model message-body description (Nested Message-body Attributes #28)

    E.g.:

    # User [/users/{id}]
    + Model
        + name (required, string, `Bob`)
        + email (optional, string, `bob@example.com`)
    
    
    # Posts [/posts/{id}]
    + Model
        + title (required, string, `Hello World`)
        + author (optional, [User][])
    
    # Users Collection [/users]
    + Model
        + [User.many][]

@zdne
Copy link
Contributor Author

zdne commented Jan 31, 2014

This issue should be fully addressed in proposed Resource Blueprint Embedded Entities – Also #13

@zdne
Copy link
Contributor Author

zdne commented May 18, 2014

I have recently put a lot of thoughts into this. And I believe it might be beneficial to allow reference expansion on the asset level.

The main premise remains: An asset must remain opaque to API Blueprint parser (parser does not interpret what is inside), unless the blueprint author specifically does instruct the parser otherwise.

Embedded Entities

On-demand Asset Expansion Proposal

A payload body's content can include a reference to a resource (model) that is expanded by the parser if and only if the body definition is preceded by the embed section specifying the respective symbol to expand.

For example:

# User [/users/{id}]
+ Model

        {"name": "Bob", "email": "bob@example.com"}

# Users [/users]
+ Model
    + Embed: [User][]
    + Body

            [[User][]]

# Blog Post [/posts/{id}]
+ Model
    + Embed: [User][]
    + Body

            {"title": "Hello World", "author": [User][] }

This should improve current situation on modeling resources that embed other resources and also to increase DRY-ness of blueprints.

Thoughts?

@zdne zdne added the feature label May 19, 2014
@BRMatt
Copy link

BRMatt commented May 19, 2014

This looks great! At the moment my only concern is that sometimes resources embed "mini" versions of other resources. By the looks of it only one model can be defined per resource. How might one use this approach to embed a mini-version of a resource without defining a new resource?

@zdne
Copy link
Contributor Author

zdne commented May 20, 2014

@BRMatt This is valid point Matt!

I am afraid that this can be achieved only by

  1. Writing the partial version anyway
  2. Using the MSON syntax to point which fields are included...

I still need to ponder this idea..

@zdne
Copy link
Contributor Author

zdne commented May 20, 2014

Note this related question: #89

@DataGreed
Copy link

Looks really good, what are the plans for assets?

@zdne
Copy link
Contributor Author

zdne commented Oct 29, 2014

I have decided to not the collection "auto generation" of this feature at the moment

e.g.

[asset.one][]
[asset.many][]
[asset.ten][]

Without it, this issue should be addressed with the introduction of MSON in the API Blueprint as discussed here.

@adamreisnz
Copy link

I'm going back and forth a bit in the documentation, examples, this issue and severak other issues in this repo, but I still can't figure out how to reference an array of JSON data in my API definition.

Can someone provide a clear example, with or without MSON, using Model or Attributes or Data Structures or whichever, as long as I can define one model somewhere, and then reference it for the body of a response, either for a targeted GET (single model) or collection GET (array of models)?

Thanks!

@kylef
Copy link
Member

kylef commented Nov 24, 2016

@adambuczynski You can find an example at https://apiblueprint.org/documentation/advanced-tutorial.html#data-structures. Where you can reference the data structure as follows for a single request/response:

+ Request (application/json)
    + Attributes (Question)

+ Response 200 (application/json)
    + Attributes (Question)

A collection of Question:

+ Response 200 (application/json)
    + Attributes (array[Question])

@adamreisnz
Copy link

adamreisnz commented Nov 24, 2016

@kylef thanks, I've seen those docs/tutorials, but that's when using data structures.
As far as I understand, I need to define these data structures at the top of my api spec which is not very comfortable. Also, I thought I read somewhere that data structures are supposed to be limited to common chunks of data, not entire models.

With the Models, I can define them for a specific endpoint, and then reuse them in the response body, but only a single Model. Can I reference a collection of models somehow?

@adamreisnz
Copy link

adamreisnz commented Nov 24, 2016

I think I've figured it out now, I just define the data structure under Attributes of the named endpoint, and then I can use the named endpoint as a reference in attributes for the response, e.g.:

## Item [/item]

+ Attributes
    + name: `Some item` (string)
    + date: `2015-08-05T08:40:51.620Z` (string)

### View item [GET /item/{itemId}]

+ Parameters
    + itemId (ObjectId, required)

+ Response 200 (application/json)
    + Attributes (Item)

### List items [GET /item]

+ Response 200 (application/json)
    + Attributes (array[Item])

This is what I was after, not very clear form the documentation and examples, as most examples include JSON in the response body and/or use Model for referencing data.

@kylef kylef reopened this Nov 25, 2016
@kylef kylef closed this as completed Nov 25, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants