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

dereference particular attribute of MSON model #52

Open
geemus opened this issue Feb 24, 2016 · 12 comments
Open

dereference particular attribute of MSON model #52

geemus opened this issue Feb 24, 2016 · 12 comments

Comments

@geemus
Copy link

geemus commented Feb 24, 2016

I find myself wanting to just dereference particular attributes of models while working on things, rather than say including the whole model (this probably relates to api-blueprint-rfcs#3). There are two cases, in particular where this is coming up. I tried to see if there was some way to do this I was missing, but didn't have luck finding anything.

I imagine this might look something like Resource[attribute], similar to the array[type] syntax, but I don't really have strong feelings in particular about the specifics.

  1. I'd like to include only a subset as attributes for requests to create . For example, created_at/updated_at and uuid are part of the data model, but are usually assigned rather than passed in the request.
  2. I'd like to be able to refer to a different data models keys, in particular for exposing foreign keys.

In both cases, it is really just a subset (or single) attribute that I want to be able to pull in, rather than duplicating the definition. Both cases mirror how I've done this in pure json-schema via prmd before, fwiw.

Hope that is relatively clear, but do let me know if you have questions or I can further clarify. Thanks!

@geemus
Copy link
Author

geemus commented Feb 24, 2016

Seems perhaps the current recommended way might be to specify just the subset I care about as it's own object and include that into the other objects, alla: https://github.com/apiaryio/api-blueprint/blob/master/examples/10.%20Data%20Structures.md

So, for the examples above:

  1. there would be a data structure for just the mutable attributes to use here and then a full data structure that included both mutable and immutable (it gets yet more complicated if the parameters allowed between create/update are different, among other cases).
  2. there could also be an identity data structure for each model which could be included in cases such as this

@geemus
Copy link
Author

geemus commented Feb 24, 2016

For reference, here is the path I went down instead. This may be sufficient, just took me a bit to reach it.

FORMAT: 1A
HOST: http://example.com/

# API

API for example purposes

## Thing [/things]

### Create Thing [POST]

+ Request (application/json)

  + Body
    + Attributes (Thing Parameters)

+ Response 201 (application/json)

  + Attributes (Thing)

# Data Structures

## Shared (object)
+ created_at: `2012-01-01T12:00:00Z` (string) - when object was created
+ id: `01234567-89ab-cdef-0123-456789abcdef` (string, fixed) - unique id of object
+ updated_at: `2012-01-01T12:00:00Z` (string) - when object was updated

## Thing (object)
+ Include Shared
+ Include Thing Parameters
+ Include User Reference

## Thing Parameters (object)
+ name: "foo" (string, required) - name for thing

## User Reference(object)

+ user (object) - user that owns this object
  + id: `01234567-89ab-cdef-0123-456789abcdef` (string) - unique id of user

@geemus
Copy link
Author

geemus commented Feb 24, 2016

One more example came up as I continued.

  1. re-referencing the object id as a url param, like in /objects/{id}.

@zdne
Copy link
Contributor

zdne commented Feb 25, 2016

Hey @geemus, first of all thank you for this much feedback on various issues! I think this might really help and improve many things!

When it comes to referencing MSON elements on the sub-named type level we still haven't came to a solution. We were considering the JSON path-like approach but at this moment I feel that working with the mixin type could be the way to go.

For the time being your findings are correct - simply split the data into multiple parts (mutable, immutable) and them pull them in using Include. Note with the mixin type you can use type attributes like so - Include (A, required) (all properties pulled from A should be now required.


Note in your example you have a superfluous body section. I believe you wanted to do just

+ Request (application/json)
    + Attributes (Thing Parameters)

instead of

+ Request (application/json)

  + Body
    + Attributes (Thing Parameters)

@zdne
Copy link
Contributor

zdne commented Feb 25, 2016

Brainstorming here. We could come up with something like

## Thing [/things]
### Create Thing [POST]

+ Request (application/json)
    + Attributes (object)
        + Include (Thing.name)
        + Include (Thing.email)

+ Response 201 (application/json)

  + Attributes (Thing)

# Data Structures

## Shared (object)
+ created_at: `2012-01-01T12:00:00Z` (string) - when object was created
+ id: `01234567-89ab-cdef-0123-456789abcdef` (string, fixed) - unique id of object
+ updated_at: `2012-01-01T12:00:00Z` (string) - when object was updated

## Thing (object)
+ name: "foo" (string, required) - name for thing
+ email: "[email protected]"
+ Include User Reference
+ Include Shared

## User Reference(object)

+ user (object) - user that owns this object
  + id: `01234567-89ab-cdef-0123-456789abcdef` (string) - unique id of user

Or even

+ Request (application/json)
    + Attributes (object)
        + Include (Thing, explicit)
                + name
                + email

Where explicit would mean that nothing is pulled in by default but you have to specify what properties to pull in.

Question is whether these approaches are worth exploring if there is some solution available...

Thoughts?

@geemus
Copy link
Author

geemus commented Feb 25, 2016

I could see either of those working, though I think I like the first include version a bit better than the one utilizing the explicit keyword. Another option I was thinking about was something like a singular version of Attributes. So maybe something like:

+ Request (application/json)
    + Attributes (object)
        + Attribute (Thing.name)

I had originally thought something like Attribute(Thing, name), but the dot syntax you suggest does seem cleaner. I don't think this really gains much over your version, and has the negative of adding a new keyword (though I suppose that should be balanced against adding more meaning/complexity to an existing keyword).

Can Attributes occur more than once in this context? Just wondering if allowing attributes to have a narrower scope might be good. Something like:

+ Request (application/json)
    + Attributes (Thing.email)
    + Attributes (Thing.name)

Kind of thinking "aloud" so to speak here. Seems like there are some positives/negatives on all of them and I'm not familiar enough with everything to be confident a couple of the options are even valid.

Thoughts?

@Perni1984
Copy link

running into the same issue here - basically solving it with @geemus suggestion by splitting the data structures.

In contrary to what has been discussed here, repeating nearly a whole model in the request attributes, just for the sake of dereferencing id, created_at, updated_at doesn't look very DRY to me.

I would propose something like that:

+ Request (application/json)
    + Attributes (Thing)
        ~ id
        ~ created_at
        ~ updated_at

@Perni1984
Copy link

btw. this seems like a duplicate of #25.

@geemus
Copy link
Author

geemus commented Feb 26, 2016

@Perni1984 that makes sense. I think with your suggestion and #25 are both slightly different than what I was talking about (though ideally this could support both). In particular I was looking to add things in a whitelist kind of way where I add each attribute individually, whereas I think you and #25 want more of a blacklist where all attributes are there by default and you can subtract the ones you do not want. Would that be an accurate assessment?

@Perni1984
Copy link

@geemus: this is an accurate assessment. I must have misread your post.

@geemus
Copy link
Author

geemus commented Feb 26, 2016

No worries, I may have been more vague/unclear than I should have been. Figured this was a good time to try and be clear though.

@phumke
Copy link

phumke commented Feb 26, 2016

I have to be a

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants