You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@usergrid.apache.org by "Brandon Shelley (JIRA)" <ji...@apache.org> on 2015/07/10 00:10:04 UTC

[jira] [Updated] (USERGRID-791) Re-evaluation connections verbiage and either deprecate or offer alternative (alias) to old terminology

     [ https://issues.apache.org/jira/browse/USERGRID-791?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Brandon Shelley updated USERGRID-791:
-------------------------------------
    Description: 
Currently the verbiage of connections is exceptionally confusing. Out of the docs, we support:

{code}
POST /users/[uuid]/likes/[uuid]
// No body?
// No target collection, just an orphaned uuid?
{code}

Which produces a structure like this:

{code}
/users/[uuid]:

{
    "metadata": {
        "connections": {
            "likes": "/users/[uuid]/likes"
        }
    }
}
{code}

To which you can then call either:

{code}GET /users/[uuid]/likes{code}

OR!

{code}GET /users/[uuid]/connections/likes{code}

OR!!! (NOT IN THE DOCS?!)

{code}GET /users/[uuid]/connected/likes{code}

Then, confusingly, on the reverse, you can call:

{code}GET /pictures/[uuid]/connecting{code}

OR

{code}GET /pictures/[uuid]/connecting/likes{code}

Needless to say, this is exceptionally amgiuous and connect* is a mouthful.

*Proposal:*

In the POST request that creates the connection, rather than relying on URL paths to confuse things, allow the user to define the parameters in the POST body instead. Rough example: 

_(Caveat: this may not architecturally work with the different "in" and "out" verbs. That's ok, even with the "in" and "out" key objects under "connections", it's still easier to understand than it is now)_

{code}
POST /[collection]/[uuid]/connect

// body:

{
    "to": "/[collection]/uuid",
    "in": "likedBy",
    "out": "likes"
}
{code}

Then when retrieving:

{code}
GET /users/[uuid]

// Can we drop this from metadata, and instead include it in the top level?
{
    "connections": {
        "out": {
            "likes": [ // should ALWAYS be an array
                "/users/[uuid]",
                "/pictures/[uuid]"
            ]
        },
        "in": {
            "likedBy": [ // should ALWAYS be an array
                "/users/[uuid]"
            ],
            "dislikedBy": [
                "/moderators/[uuid]"
            ]
        }
    }
}
{code}

Or, call it specifically:

{code}
GET /users/[uuid]/likes:

[ ... array of entities that [uuid] likes ... ]

{code}

Or, call it specifically:

{code}
GET /users/[uuid]/likedBy:

[ ... array of entities that like [uuid] ... ]

{code}

Or, call relationships:

{code}
GET /users/[uuid]/connections/in

[ ... array of entities that have inbound connections to [uuid] ... ]

{code}

{code}
GET /users/[uuid]/connections/out

[ ... array of entities that [uuid] has outbound connections to ... ]

{code}

{code}
GET /users/[uuid]/connections:

[ ... a mixed array of ALL entities connected to and from [uuid], ordered by created date; 'type' would distinguish which collection each entity belongs to ... ]

{code}

*BONUS POINTS*

Connections are a pain in the ass because you ALWAYS need to make 2 API calls in order to retrieve them. Let's add a paremeter to optionally resolve them (yes, slow, that's OK - we can just add a disclaimer to docs). To make it performant, we could include the cursor from the nested relationship array.

{code}
GET /users/[uuid]?resolveConnections=likes
(or!) 
GET /users/[uuid]?resolveConnections=likes:uuid,name,firstName

{
    "connections": {
        "in": {
            "likesCursor": "pagiationCursorGoesHere",
            "likes": [ // should ALWAYS be an array
                {
                    // an entity! But only this one is expanded
                },
                {
                    // an entity! But only this one is expanded
                }
            ]
        },
        "out": {
            "likedBy": [ // should ALWAYS be an array
                "/users/[uuid]"
            ],
            "dislikedBy": [
                "/moderators/[uuid]"
            ]
        }
    }
}
{code}

  was:
Currently the verbiage of connections is exceptionally confusing. Out of the docs, we support:

{code}
POST /users/[uuid]/likes/[uuid]
// No body?
// No target collection, just an orphaned uuid?
{code}

Which produces a structure like this:

{code}
/users/[uuid]:

{
    "metadata": {
        "connections": {
            "likes": "/users/[uuid]/likes"
        }
    }
}
{code}

To which you can then call either:

{code}GET /users/[uuid]/likes{code}

OR!

{code}GET /users/[uuid]/connections/likes{code}

OR!!! (NOT IN THE DOCS?!)

{code}GET /users/[uuid]/connected/likes{code}

Then, confusingly, on the reverse, you can call:

{code}GET /pictures/[uuid]/connecting{code}

OR

{code}GET /pictures/[uuid]/connecting/likes{code}

Needless to say, this is exceptionally amgiuous and connect* is a mouthful.

*Proposal:*

In the POST request that creates the connection, rather than relying on URL paths to confuse things, allow the user to define the parameters in the POST body instead. Rough example: 

{code}
POST /[collection]/[uuid]/connect

// body:

{
    "to": "/[collection]/uuid",
    "in": "likedBy",
    "out": "likes"
}
{code}

Then when retrieving:

{code}
GET /users/[uuid]

// Can we drop this from metadata, and instead include it in the top level?
{
    "connections": {
        "out": {
            "likes": [ // should ALWAYS be an array
                "/users/[uuid]",
                "/pictures/[uuid]"
            ]
        },
        "in": {
            "likedBy": [ // should ALWAYS be an array
                "/users/[uuid]"
            ],
            "dislikedBy": [
                "/moderators/[uuid]"
            ]
        }
    }
}
{code}

Or, call it specifically:

{code}
GET /users/[uuid]/likes:

[ ... array of entities that [uuid] likes ... ]

{code}

Or, call it specifically:

{code}
GET /users/[uuid]/likedBy:

[ ... array of entities that like [uuid] ... ]

{code}

Or, call relationships:

{code}
GET /users/[uuid]/connections/in

[ ... array of entities that have inbound connections to [uuid] ... ]

{code}

{code}
GET /users/[uuid]/connections/out

[ ... array of entities that [uuid] has outbound connections to ... ]

{code}

{code}
GET /users/[uuid]/connections:

[ ... a mixed array of ALL entities connected to and from [uuid], ordered by created date; 'type' would distinguish which collection each entity belongs to ... ]

{code}

*BONUS POINTS*

Connections are a pain in the ass because you ALWAYS need to make 2 API calls in order to retrieve them. Let's add a paremeter to optionally resolve them (yes, slow, that's OK - we can just add a disclaimer to docs). To make it performant, we could include the cursor from the nested relationship array.

{code}
GET /users/[uuid]?resolveConnections=likes
(or!) 
GET /users/[uuid]?resolveConnections=likes:uuid,name,firstName

{
    "connections": {
        "in": {
            "likesCursor": "pagiationCursorGoesHere",
            "likes": [ // should ALWAYS be an array
                {
                    // an entity! But only this one is expanded
                },
                {
                    // an entity! But only this one is expanded
                }
            ]
        },
        "out": {
            "likedBy": [ // should ALWAYS be an array
                "/users/[uuid]"
            ],
            "dislikedBy": [
                "/moderators/[uuid]"
            ]
        }
    }
}
{code}


> Re-evaluation connections verbiage and either deprecate or offer alternative (alias) to old terminology
> -------------------------------------------------------------------------------------------------------
>
>                 Key: USERGRID-791
>                 URL: https://issues.apache.org/jira/browse/USERGRID-791
>             Project: Usergrid
>          Issue Type: Story
>          Components: Stack
>    Affects Versions: 2.0
>            Reporter: Brandon Shelley
>              Labels: features
>
> Currently the verbiage of connections is exceptionally confusing. Out of the docs, we support:
> {code}
> POST /users/[uuid]/likes/[uuid]
> // No body?
> // No target collection, just an orphaned uuid?
> {code}
> Which produces a structure like this:
> {code}
> /users/[uuid]:
> {
>     "metadata": {
>         "connections": {
>             "likes": "/users/[uuid]/likes"
>         }
>     }
> }
> {code}
> To which you can then call either:
> {code}GET /users/[uuid]/likes{code}
> OR!
> {code}GET /users/[uuid]/connections/likes{code}
> OR!!! (NOT IN THE DOCS?!)
> {code}GET /users/[uuid]/connected/likes{code}
> Then, confusingly, on the reverse, you can call:
> {code}GET /pictures/[uuid]/connecting{code}
> OR
> {code}GET /pictures/[uuid]/connecting/likes{code}
> Needless to say, this is exceptionally amgiuous and connect* is a mouthful.
> *Proposal:*
> In the POST request that creates the connection, rather than relying on URL paths to confuse things, allow the user to define the parameters in the POST body instead. Rough example: 
> _(Caveat: this may not architecturally work with the different "in" and "out" verbs. That's ok, even with the "in" and "out" key objects under "connections", it's still easier to understand than it is now)_
> {code}
> POST /[collection]/[uuid]/connect
> // body:
> {
>     "to": "/[collection]/uuid",
>     "in": "likedBy",
>     "out": "likes"
> }
> {code}
> Then when retrieving:
> {code}
> GET /users/[uuid]
> // Can we drop this from metadata, and instead include it in the top level?
> {
>     "connections": {
>         "out": {
>             "likes": [ // should ALWAYS be an array
>                 "/users/[uuid]",
>                 "/pictures/[uuid]"
>             ]
>         },
>         "in": {
>             "likedBy": [ // should ALWAYS be an array
>                 "/users/[uuid]"
>             ],
>             "dislikedBy": [
>                 "/moderators/[uuid]"
>             ]
>         }
>     }
> }
> {code}
> Or, call it specifically:
> {code}
> GET /users/[uuid]/likes:
> [ ... array of entities that [uuid] likes ... ]
> {code}
> Or, call it specifically:
> {code}
> GET /users/[uuid]/likedBy:
> [ ... array of entities that like [uuid] ... ]
> {code}
> Or, call relationships:
> {code}
> GET /users/[uuid]/connections/in
> [ ... array of entities that have inbound connections to [uuid] ... ]
> {code}
> {code}
> GET /users/[uuid]/connections/out
> [ ... array of entities that [uuid] has outbound connections to ... ]
> {code}
> {code}
> GET /users/[uuid]/connections:
> [ ... a mixed array of ALL entities connected to and from [uuid], ordered by created date; 'type' would distinguish which collection each entity belongs to ... ]
> {code}
> *BONUS POINTS*
> Connections are a pain in the ass because you ALWAYS need to make 2 API calls in order to retrieve them. Let's add a paremeter to optionally resolve them (yes, slow, that's OK - we can just add a disclaimer to docs). To make it performant, we could include the cursor from the nested relationship array.
> {code}
> GET /users/[uuid]?resolveConnections=likes
> (or!) 
> GET /users/[uuid]?resolveConnections=likes:uuid,name,firstName
> {
>     "connections": {
>         "in": {
>             "likesCursor": "pagiationCursorGoesHere",
>             "likes": [ // should ALWAYS be an array
>                 {
>                     // an entity! But only this one is expanded
>                 },
>                 {
>                     // an entity! But only this one is expanded
>                 }
>             ]
>         },
>         "out": {
>             "likedBy": [ // should ALWAYS be an array
>                 "/users/[uuid]"
>             ],
>             "dislikedBy": [
>                 "/moderators/[uuid]"
>             ]
>         }
>     }
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)