Feedback on Contacts API, informed by some Firefox Contacts prototyping

Hello, list - I've been keeping a list of feedback items that have come up as I work on the Firefox Contacts prototype and read through the latest version of the Contacts API.  If you would like me to attach this to a wiki page please let me know as well.  I've broken my feedback down into architecture, API, and schema items.

Architectural

Concurrency:

The asynchronous pattern is smart and appropriate for the web developer community.  

It causes some complications because of the possibility of queries overlapping in time.  I would like to see a small amount of commentary about what implementors should do to address concurrency issues.  The creation of a PendingOp in these cases introduces the possibility of a rollback, complicating things further.  Are implementors required to enforce serialization, so that, e.g. a find() won't pick up records that have been removed() but not yet committed?  Or is an eventually-consistent approach sufficient?  Is each tab required to be coherent, or is coherency across tabs required?

Also, there are subtleties associated with pending operations that are still inflight when a browser window is closed, or a browser-termination event is initiated.  Are those PendingOps implicitly cancelled?  Or are we required to make a best-effort to see them complete?  We should get feedback from the runtime experts about whether the proposed API for PendingOp is going to work in those cases.

Uniqueness

I am not sure the UUID requirement is realistic in practice, though I appreciate the desire for it.  More language about the intent of the field could help.  The clone() method makes a new ID, I see, but I don't see how that's supposed to interact with potentially remote contact providers.  And it's not clear how a contact synchronization system should interact with the UUID -- if a mobile is sync'ed with a desktop address book, are UUIDs preserved?  

Is the UUID intended for use as an internal identifier for the convenience of applications running in a single web app context for a single session, or is it intended to be used as a correlation token that persists indefinitely?  (I'm bringing my own baggage here, as the Firefox Contacts prototype unifies contact identities across numerous services, but I think the spec would benefit from more clarity on this point).

API:

The general pattern of the API is good - the "Contacts" class acts as a factory where necessary, and everything else is handled by "Contact" objects.  

I predict that implementors will encounter some pain when bulk edits are needed, since the current scheme requires a single-object-at-a-time pattern; for example, deleting all contacts with a given serviceId could be very slow.  The only way around that would be to add more bulk operations to "Contacts" -- e.g. Contacts.delete( {filterExpression} ).  That may be premature at this point but I predict some implementation pain here.

Nulling of unknown attributes

The underlying assumption here is that the schema is fully normative, yes?  I'm okay with that in general, though (as I note in the section below) I'd really rather start from an existing schema and make assertions about which fields are mandatory and which must be removed.

multiple option

The presence of "multiple" in the options suggests that a behavior should be defined in (7) to indicate which match wins in the non-multiple case.  First one wins?

Caller provides list of fields

I am partial to an option that allows the web content to indicate which fields of the person record they want (which allows us to construct a UI where the user grants, or denies, access to individual fields).  The presumption is that web content would never receive more data than they asked for, and may receive less.  I may be mistaken but I thought this feature was in an earlier draft?

RFC2119 and Section 4.2:

The use of MUST language to restrict the behavior of a website that acts as a client to Contacts is a nice thought but feels totally unenforceable.  RFC2119 is intended to protect protocol interoperability, not to make moral claims about the use of an API, and using it in this way muddies the water a bit.  The fact is, bad actors will attempt to abuse this API, and in some cases they will succeed; we should put our effort into countermeasures.

Section 4.3 is closer to the mark; we may want to think about (e.g.) adding something to options to allow the site include language or icons to assert a particular privacy policy to the user during disclosure.

Schema/ContactProperties:

I was a bit disappointed to see yet another schema for people.  I would prefer to see a personal data schema that already has some standardization effort behind it, such as Portable Contacts or hCard.  The adoption of a standard scheme like Portable Contacts would also give us a standard way of handling extensions, something which is not present in the current draft.

I note that the schema presented in the draft does not include birthday, which was demanded by one of the use cases in a prior draft.  A standardized schema that has already been through community review would help avoid omissions like that.

My preference would be for Portable Contacts, which is imperfect but has some momentum at this point.  

With regard to the schema as proposed in the draft, my feedback is:

* The draft defines "name" as a singular field, which is insufficient for most applications and is particularly difficult for some localizations.  A givenName and familyName is important, and cultural norms differ about to handle these two fields.  Many mobile applications also demand a phonetic name field to enable voice recognition hints.  A structured "name" field leads to the desire for a "displayName", which would be identical to the "name" currently present in the draft.  Parsing human names is a really painful problem and if we have structured data I'd really prefer to maintain it.

* Portable Contacts defines both a "username" and a "userid" field for the "accounts" field, which is analogous to the draft's "impps".  The distinction between a human-readable identifier and a system identifier is sometimes useful.  PoCo also defines a "domain" property for "accounts", which allows for a semi-restricted vocabulary -- an application can search for equality with "yahoo.com" instead of using a substring match or other more complicated approach.

* Is an extension mechanism formally off the table?  

Best,
Michael Hanson
--
Michael Hanson, Mozilla Labs (@michaelrhanson)

Received on Tuesday, 1 June 2010 16:50:28 UTC