Clarification on RESTful People API, connections vs. contact records, and invitation workflow

0 views
Skip to first unread message

John Panzer

unread,
Jun 24, 2008, 9:08:46 PM6/24/08
to opensocial-an...@googlegroups.com
All,

There's been some discussion about how the People RESTful API operates in the context of Friends, in particular:
1. When you don't actually have the power to just insert something into 'your' @friends collection, because friending requires double opt-in from both parties; and
2. When the records you get in @friends are actually information provided by the social network on behalf of your friends, that is, the records represent _connections_ to a person in the network rather than a static collection of fields.

The spec is somewhat ambiguous on these points, because it wants to support all kinds of containers, not just those with constraints 1 and 2.  However, for containers with those constraints, it makes a lot of sense to document how the RESTful API is supposed to work.  I'd like to propose a clarification to the spec text that would be a version of the following; comments and suggestions welcomed.

------SPEC TEXT----
The RESTful API supports containers where friending involves an invitation process and where friend records actually represent live, filtered views of other people's profiles; in fact this is the common case today.  This note describes the intended semantics of the RESTful API in these cases.

To invite a friend, you POST a sufficiently identifying representation of the friend to your own @friends group.  Containers SHOULD allow invitation with nothing more than an email (emails are universally unique).  Containers MAY allow invitation via other attributes, for example, OpenID, user/login information, telephone number, or address.  In this case a client is asking the container to create a connection (represented as a Person) given the submitted data; the container may nor may not honor the request, and if it honors the request, it MAY not do so immediately.

If it _does_ honor the request immediately, it MUST respond with a 201 Created response and return a Location: header pointing to the newly created connection.  Note that the container MAY modify any or all fields submitted when creating the connection; for example, it MAY modify the email address to be the new/default email address specified by the other user.

If it does not honor the request, but must start additional workflow, it MUST respond with a 202 Accepted response and a Location: header pointing to where the record will be once the workflow successfully completes.  Workflow might include an opt-in from the other party, moderation or rate limiting, or any other process that must complete asynchronously to the RESTful API.  The client can check the URI returned, if necessary, to see if the workflow has completed; it SHOULD respond with a 404 Not Found until the workflow is completed, after which it SHOULD respond with a 200. 

DELETEing a Person resource which is actually a connection simply removes the connection (unilaterally). 

PUTting modified data to a Person resource which is a connection may or may not be allowed, depending on the container.  For example, some containers may allow people to assign useful nicknames to their connections (not visible to the connections), or augment the available information with additional data.  However, containers are not required to support this and MAY provide only a read-only view of the data, in which case PUT SHOULD result in a 405 Method Not Allowed error.

Note that PUTting to the @self record for the current user allow modification of one's own profile data.  Containers MAY also allow DELETE to let a user remove themselves from the network entirely, but are not required to do so; again, if this method is not suported, 405 Method Not Allowed is the appropriate response.

Some networks do not require double opt in, but provide connection semantics if there _is_ double opt in.  (The AIM IM network, if represented in OpenSocial, would be an example of this; you are free to add anyone to your buddy list given their screen name, but they do not necessarily get a notification of this, and you do not get any presence information or other updates unless they also add you as a buddy.)  In this case, the POST would always return a 201 Created, but the record would be 'static' until and unless the person on the other end does the reverse operation.

Conflicts:  In some cases, attempting to add a second friend may have a primary key conflict with an existing friend.  In this case, containers SHOULD return a 409 Conflict status and a Location: header pointing at the other (conflicting) resource.  For example, if a person with the primary email john...@example.org already exists, an attempt to POST a resource with an email john...@example.org MAY fail with a 409 response.  Containers MAY define their own rules for conflicting keys and MAY not attempt any conflict detection at all, simply assigning each new record a new unique internal identifier.

----END OF SPEC TEXT---


John Panzer (http://abstractioneer.org)

David Primmer

unread,
Jun 24, 2008, 9:36:45 PM6/24/08
to opensocial-an...@googlegroups.com
Thank you John! This is what I was hoping for when I asked for better
write semantics. This is great stuff! One comment below:

On Tue, Jun 24, 2008 at 6:08 PM, John Panzer <jpa...@google.com> wrote:
> All,
>
> There's been some discussion about how the People RESTful API operates in
> the context of Friends, in particular:
> 1. When you don't actually have the power to just insert something into
> 'your' @friends collection, because friending requires double opt-in from
> both parties; and
> 2. When the records you get in @friends are actually information provided by
> the social network on behalf of your friends, that is, the records represent
> _connections_ to a person in the network rather than a static collection of
> fields.
>

I think I know what you're getting at here but it's a little vague. #2
is a situation where people/john.doe/@friends returns a collection of
people resources that are actual resources on the social network that
could be accessed via userid, such that if you got back 'jane.doe' id
in the collection, you could do /people/jane.doe/@self and get her
profile. In fact, the default representation of @friends is assumed to
be a collection of full profile resources for those people. (This is
the way it's done in shindig, you could also just return links to the
resources themselves.)

When you refer to a "static collection of fields" are you saying
something like a private data set (like an email address book record)
that is only usable by the user in question and not globally available
resources on the social network?

davep

John Panzer

unread,
Jun 24, 2008, 9:45:46 PM6/24/08
to opensocial-an...@googlegroups.com


John Panzer (http://abstractioneer.org)

On Tue, Jun 24, 2008 at 6:36 PM, David Primmer <david....@gmail.com> wrote:

Thank you John! This is what I was hoping for when I asked for better
write semantics. This is great stuff! One comment below:

On Tue, Jun 24, 2008 at 6:08 PM, John Panzer <jpa...@google.com> wrote:
> All,
>
> There's been some discussion about how the People RESTful API operates in
> the context of Friends, in particular:
> 1. When you don't actually have the power to just insert something into
> 'your' @friends collection, because friending requires double opt-in from
> both parties; and
> 2. When the records you get in @friends are actually information provided by
> the social network on behalf of your friends, that is, the records represent
> _connections_ to a person in the network rather than a static collection of
> fields.
>

I think I know what you're getting at here but it's a little vague. #2
is a situation where people/john.doe/@friends returns a collection of
people resources that are actual resources on the social network that
could be accessed via userid, such that if you got back 'jane.doe' id
in the collection, you could do /people/jane.doe/@self and get her
profile. In fact, the default representation of @friends is assumed to
be a collection of full profile resources for those people. (This is
the way it's done in shindig, you could also just return links to the
resources themselves.)

Yeah, I'm not sure that actually works, and this is what Cassie and I argued about a while back.  That is, it's fine for Shindig to make /people/jane.doe/@all/john.doe just return exactly the same data as /people/john.doe/@self.  But, the semantics of

DELETE /people/jane.doe/@all/john.doe
and
DELETE /people/john.doe/@self

are very different (as are the semantics of PUT, and the semantics of POST if we allowed POST to /people which I suppose a container could allow as an extension...)  In other words, while the data is just aliased, the resource itself is not the same in a read/write world.

 


When you refer to a "static collection of fields" are you saying
something like a private data set (like an email address book record)
that is only usable by the user in question and not globally available
resources on the social network?

Yes, exactly -- just like a card in a Rolodex (you know, I'm not sure if even I ever used a Rolodex, but my parents had one when I was a kid.)



 
Reply all
Reply to author
Forward
0 new messages