<?xml version="1.0"?>
<!DOCTYPE content [ <!ENTITY nbsp " "> ]>
<rdf:RDF xml:base="http://snarfed.org/rdf"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/">

<rdf:Description rdf:about="http://snarfed.org">
  <dc:title> snarfed.org  </dc:title>
  <dc:description> draw group stream of consciousness </dc:description>
  <dc:creator> Ryan Barrett &lt;snarfed at ryanb dot org&gt; </dc:creator>
  <dc:language> en </dc:language>
  <dc:format> text/html </dc:format>
  <dc:rights> Copyright 2002-2007 Ryan Barrett </dc:rights>
</rdf:Description>

<rdf:Description rdf:about="http://snarfed.org/space/facebook%20data%20store%20api%20thoughts">
  <dc:title> Facebook Data Store API Thoughts </dc:title>
  <dc:creator> Ryan Barrett &lt;snarfed at ryanb dot org&gt; </dc:creator>
  <dc:date> 2007-08-09T21:56:00Z </dc:date>
  <dc:language> en </dc:language>
  <dc:format> text/html </dc:format>
  <dc:rights> Copyright 2002-2007 Ryan Barrett </dc:rights>

  <content>
    <div style="float: right; margin-left: 10px">
  <a href="http://wiki.developers.facebook.com/index.php/Data_Store_API_documentation">
   <img src="/space/facebook_platform_logo.png" /></a>
</div>

<p>On Monday,
<a href="http://facebook.com/">Facebook</a> employee
<a href="http://www.facebook.com/s.php?q=haiping+zhao&amp;n=50431648">Haiping Zhao</a>
quietly published a
<a href="http://wiki.developers.facebook.com/index.php/Data_Store_API_documentation">Data Store API</a>
on the
<a href="http://wiki.developers.facebook.com/">Facebook developer wiki</a>.</p>

<p>It's preliminary, and still in closed beta, but it marks a milestone in the
evolution of the Facebook platform. It could be an indication of the
direction Facebook plans to take the platform in the future.</p>

<p>Here are some of my thoughts on this API, as well as a few responses from
Haiping, in <em>italics</em>. Feel free to <a href="/space/facebook+data+store+api+thoughts#comment-anchor">add your own</a>!</p>

<h3>Contents</h3>

<p><a href="/space/facebook+data+store+api+thoughts#intro">Introduction</a> <br />
<a href="/space/facebook+data+store+api+thoughts#schema">Schema definition</a> <br />
<a href="/space/facebook+data+store+api+thoughts#data_access">Data access</a> <br />
<a href="/space/facebook+data+store+api+thoughts#transactions">Transactions</a> <br />
<a href="/space/facebook+data+store+api+thoughts#associations">Associations</a> <br />
<a href="/space/facebook+data+store+api+thoughts#preferences">Preferences</a></p>

<p><a name="intro"></a></p>

<h3><a href="/space/facebook+data+store+api+thoughts#intro"><img src="/Icon-Permalink.png" alt="Icon-Permalink.png" title="" /></a> Introduction</h3>

<p>The Facebook data store is a very simple hosted database, accessible
by a
<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</a>
<a href="http://en.wikipedia.org/wiki/CRUD_(acronym)">CRUD</a> API. It supports both XML and JSON. It requires users to define their schema, and has basic create, read, update, and
delete operations, but no structured queries, full text search, or transactions.</p>

<p>The one truly interesting feature it does provide is
<a href="/space/facebook+data+store+api+thoughts#associations">associations</a>, which are foreign keys, with all the usual
constraints, but at the <em>row</em> level, not the table level. These may be
powerful enough to provide an alternative to querying on property values.</p>

<p>So far, the API is very limited. Still, the sources of inspiration - SQL and
social networking - are obvious even in this first draft. It will be
interesting to see how it evolves.</p>

<p><a name="schema"></a></p>

<h3><a href="/space/facebook+data+store+api+thoughts#schema"><img src="/Icon-Permalink.png" alt="Icon-Permalink.png" title="" /></a> Schema definition</h3>

<p>As with most databases, Facebook apps must define their schema up front. A
schema consists of
<a href="http://wiki.developers.facebook.com/index.php/Data.createObjectType">object types</a>,
ie tables, and
<a href="http://wiki.developers.facebook.com/index.php/Data.defineObjectProperty">properties</a>,
ie columns. Object types and property names are strings, alphanumeric plus
underscores, 32 characters or less. Property values can be small strings, large
text blobs, or integers. It looks like any or all of an object's properties can
be unset, as if they were <code>NULLABLE</code> SQL columns.</p>

<p>Schemas can be modified at runtime. Object types and properties can be
queried, added, removed, and renamed. These are similar to the SQL
<code>CREATE TABLE</code>, <code>ALTER TABLE</code>, AND <code>DROP TABLE</code> commands; in particular,
<a href="http://wiki.developers.facebook.com/index.php/Data.dropObjectType"><code>dropObjectType</code></a>
and
<a href="http://wiki.developers.facebook.com/index.php/Data.undefineObjectProperty"><code>undefineObjectProperty</code></a>
delete existing objects and property values along with the corresponding
object types and property definitions.</p>

<p>Questions:</p>

<p>The description of the
<a href="http://wiki.developers.facebook.com/index.php/Data.createObject#Parameters"><code>properties</code></a>
parameter in
<a href="http://wiki.developers.facebook.com/index.php/Data.createObject"><code>createObject</code></a>
and
<a href="http://wiki.developers.facebook.com/index.php/Data.updateObject"><code>updateObject</code></a>
seems to imply that some or all any or all of an object's properties may be
undefined. Is that true?</p>

<p>In most calls that handle property values, like setObjectProperty and
set/getHashValue, properties are sent and returned as strings. Does that mean
developers need to serialize integer properties manually? If so, that's
unfortunate at best, and dangerous at worst.</p>

<blockquote>
  <p>We were facing a decision between a strongly typed model vs. a
  weakly typed model in handling return values.</p>
</blockquote>

<p><a name="data_access"></a></p>

<h3><a href="/space/facebook+data+store+api+thoughts#data_access"><img src="/Icon-Permalink.png" alt="Icon-Permalink.png" title="" /></a> Data access</h3>

<p>The API includes the standard
<a href="http://wiki.developers.facebook.com/index.php/Data.createObject">create</a>,
<a href="http://wiki.developers.facebook.com/index.php/Data.getObject">get</a>,
<a href="http://wiki.developers.facebook.com/index.php/Data.updateObject">update</a>,
and
<a href="http://wiki.developers.facebook.com/index.php/Data.deleteObject">delete</a>
operations. In addition, there are get and delete operations that can operate
on multiple objects, and operations that get and set a subset of an object's
properties. There are even dedicated objects for getting and setting a single
property. Whether that's syntactic sugar or API bloat is left to the reader.</p>

<p>When an object is created, it's assigned a 64-bit integer
<a href="http://wiki.developers.facebook.com/index.php/Data.createObject#Return_Value"><code>fbid</code></a>,
which serves as its primary key. The <code>fbid</code> namespace and characteristics are
still unclear, but they're used in other parts of the Facebook API, outside of
the data store.</p>

<p>Objects can also be identified by
<a href="http://wiki.developers.facebook.com/index.php/Data.getHashValue">hash keys</a>.
Hash keys are described as "string object identifiers," but there's not much
information on them beyond that. They may just be a string encoding of the
<code>fbid</code>, for use in URLs and other string contexts.</p>

<p>Questions:</p>

<p>How are <code>fbid</code>s allocated? Is there a single global <code>fbid</code> namespace, or
is it per app?</p>

<blockquote>
  <p>An <code>fbid</code> is a GUID, a globally unique identifier. Well, it's actually a
  UUID, universally unique identifier, in case Mars has life and computers.</p>
</blockquote>

<p>What are hash keys? When would they be used?</p>

<blockquote>
  <p>It's an arbitrary string application defines. So, it could be a URL, if an
  application elects to do so.</p>
</blockquote>

<p>General-purpose queries based on property values are an important feature in
most data stores, but they're conspicuously absent here. Will they ever be
added?</p>

<blockquote>
  <p>In fact, you could do that through
  <a href="http://developers.facebook.com/documentation.php?doc=fql">FQL</a>. In FQL, any
  property can appear in WHERE clause.</p>
</blockquote>

<p>What are the practical limits on scaling? How many objects could an app
realistically store? How many object types? Properties per object type?
Associations? etc.</p>

<blockquote>
  <p>Facebook Data Store API is designed to be scalable, although we will have
  resource limit imposed to make fair use between different applications. Quota
  will be documented when we have them.</p>
</blockquote>

<p><a name="transactions"></a></p>

<h3><a href="/space/facebook+data+store+api+thoughts#transactions"><img src="/Icon-Permalink.png" alt="Icon-Permalink.png" title="" /></a> Transactions</h3>

<p>Despite the heading of this section, there are no general-purpose transactions
in the Facebook data store API. Fortunately, there is an
<a href="http://wiki.developers.facebook.com/index.php/Data.incHashValue">atomic increment operation</a>.
It can increment or decrement an integer property value by any amount.
This is obviously no substitute for full-fledged transactions, but it can
handle a surprising number of use cases.</p>

<p>One odd quirk is that the increment operation <em>requires</em> a hash key. Unlike
the CRUD operations, there's no corresponding increment operation that takes
an <code>fbid</code>.</p>

<p>Questions:</p>

<p>Will more transactional capabilities be added? Or is atomic increment the
best we can hope for?</p>

<blockquote>
  <p>Not in consideration currently, due to distributed nature of data objects.</p>
</blockquote>

<p><a name="associations"></a></p>

<h3><a href="/space/facebook+data+store+api+thoughts#associations"><img src="/Icon-Permalink.png" alt="Icon-Permalink.png" title="" /></a> Associations</h3>

<p><a href="http://wiki.developers.facebook.com/index.php/Data_Store_API_documentation#Association_Data_Definition_API">Associations</a>
are by far the most intriguing part of the data store API. They're
<a href="http://en.wikipedia.org/wiki/Foreign_key">foreign keys</a>,
but they can be one-way or bidirectional, and, unlike SQL, they're set at
the <em>object</em> level instead of the object type level.</p>

<p>Similar to object types and properties, associations are a kind of
<a href="/space/facebook+data+store+api+thoughts#schema">schema</a>. Association types have string names, they must be
<a href="http://wiki.developers.facebook.com/index.php/Data.defineAssociation">defined</a>
ahead of time, and they can be queried and modified on the fly.</p>

<p>More importantly, associations have properties and constraints traditionally
found in both foreign keys and graph theory. They can be one-way or two-way,
and two-way associations can be <em>symmetric</em>, where A=>B is equivalent to B=>A,
or <em>asymmetric</em>, where A=>B and B=>A mean different things, and can have
different names. Also, each endpoint of an association may be classified as
<em>unique</em>, which enforces a one-to-many or many-to-one relationship, as opposed
to the default many-to-many. See the
<a href="http://wiki.developers.facebook.com/index.php/Data.defineAssociation"><code>defineAssociation</code></a>
page for more.</p>

<p>Associations can be
<a href="http://wiki.developers.facebook.com/index.php/Data.setAssociation">set</a>,
<a href="http://wiki.developers.facebook.com/index.php/Data.removeAssociation">removed</a>,
and
<a href="http://wiki.developers.facebook.com/index.php/Data.getAssociatedObjects">queried</a>
in the expected ways. In particular, there are operations to get
<a href="http://wiki.developers.facebook.com/index.php/Data.getAssociations">all associations between <em>two</em> objects</a>
as well as
<a href="http://wiki.developers.facebook.com/index.php/Data.getAssociatedObjects">all objects associated with a given object</a>,
along with corresponding operations to get the <em>number</em> of associations and
associated objects.</p>

<p>It's easy to see how these kinds of object-level relationships can be very
powerful in a social networking application. Apps can use these to define
custom relationships and connections between people beyond the existing ones
that Facebook provides. Beyond that, apps could let users create objects of any
type - classes, books, movies, pets - and then connect them to people, and to
each other, in new ways.</p>

<p>Questions:</p>

<p>Even in this first draft, associations are very powerful and useful. It's
interesting that they're handled separately from properties, though, and that
they can't be set automatically, similar to traditional foreign keys. If that
was added, would it be a net gain?</p>

<p>What happens if i create an invalid association, e.g. one that violates a
uniqueness constraint? The
<a href="http://wiki.developers.facebook.com/index.php/Data.setAssociation">setAssociation</a>
calls don't have return values, and there aren't any association-specific error
codes.</p>

<blockquote>
  <p>It returns an invalid operation error, although we may consider to special
  case the error code.</p>
</blockquote>

<p>Are the counting methods efficient? Specifically, are they roughly constant
time, or linear? I can see how they'd be very useful for large associations,
but if they're no faster than calling
<a href="http://wiki.developers.facebook.com/index.php/Data.getAssociatedObjects"><code>getAssociatedObjects</code></a>,
that makes them less useful.</p>

<blockquote>
  <p>Constant time. This should be documented. There is one more difference from
  calling getAssociatedObjects() then count, because we have an upper limit on
  how many associated object ids to return. This is missing from documentation,
  too.</p>
</blockquote>

<p><a name="preferences"></a></p>

<h3><a href="/space/facebook+data+store+api+thoughts#preferences"><img src="/Icon-Permalink.png" alt="Icon-Permalink.png" title="" /></a> Preferences</h3>

<p>The API has separate, dedicated storage for
<a href="http://wiki.developers.facebook.com/index.php/Data_Store_API_documentation#User_Preference_API">per-app user preferences</a>.
A user preference is simply a string key/value pair. Unlike objects and
properties, though, preference names don't have to be defined up front, and
different users can have different preference names as well as values.</p>

<p>Apart from that twist, the preferences API is fairly straightforward and
unsurprising.</p>

<p>See also:</p>

<ul>
<li><a href="/space/amazon+simpledb+thoughts">Amazon SimpleDB Thoughts</a></li>
</ul>

  </content>

  <rdf:Seq>

<rdf:li>
<rdf:Description rdf:about="#1186761651.66">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> facebook data store api thoughts </dc:title>
  <dc:creator> jsled </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    Ah yes ... yet another "REST"ful API that doesn't really exhibit any of the properties of REST other than (mis)using HTTP.
  </content>
</rdf:Description>
</rdf:li>

<rdf:li>
<rdf:Description rdf:about="#1186897853.52">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> facebook data store api thoughts </dc:title>
  <dc:creator> ryan </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    mind elaborating? do you mean that it's not stateless? sure, the calls need an api key and a session id, but i expect the former is just for quotas and throttling, and the latter is just the facebook user who owns the data. i don't know that those disqualify it from claiming RESTfulness.
  </content>
</rdf:Description>
</rdf:li>

<rdf:li>
<rdf:Description rdf:about="#1191990439.33">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> facebook data store api thoughts </dc:title>
  <dc:creator> Paul </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    i wrote a php client lib for people too impatient to wait for the official one from facebook... it just extends the existing classes, shouldn't break anything - <a href="http://mysticspiral.org/facebook_datastore.php.gz">http://mysticspiral.org/facebook_datastore.php.gz</a> - also, your openid validator submitted a messed up url and wouldn't let me authenticate :/
  </content>
</rdf:Description>
</rdf:li>

<rdf:li>
<rdf:Description rdf:about="#1192202130.55">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> facebook data store api thoughts </dc:title>
  <dc:creator> Kostya </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    Paul, thank you for client lib.<br />
The only issue I found is in the function data_setUserPreference as a parameters you used 'pref_id' and 'string' where it should be 'pref_id' and <b>'value'</b><br />
Best regards..
  </content>
</rdf:Description>
</rdf:li>

<rdf:li>
<rdf:Description rdf:about="#1199562273.37">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> Facebook Data Store API Thoughts </dc:title>
  <dc:creator> joel </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    Don't know if anyone is interested, but I've just released a simple C# wrapper to the Facebook Data Store API complete with source at <a href="http://www.codeplex.com/facebookdatastoreapi">http://www.codeplex.com/facebookdatastoreapi</a>.<br />
<br />
Hope it's of some use to someone.<br />
<br />
Cheers,<br />
<br />
j
  </content>
</rdf:Description>
</rdf:li>

<rdf:li>
<rdf:Description rdf:about="#1200713295.93">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> Facebook Data Store API Thoughts </dc:title>
  <dc:creator> Dorai Thodla </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    Does FB define a set of schemas for existing associations? Is there a kind of type hierarchy for associations? This may provide an extension mechanism for relationship between members.
  </content>
</rdf:Description>
</rdf:li>

<rdf:li>
<rdf:Description rdf:about="#1207838335.91">
  <dc:source> http://snarfed.org/ </dc:source>
  <dc:title> Facebook Data Store API Thoughts </dc:title>
  <dc:creator> Mark D. </dc:creator>
  <dc:date> cmt_pubDate </dc:date>
  <dc:format> text/html </dc:format>

  <content>
    Regarding resource limits:<br />
&lt;&lt;Facebook Data Store API is designed to be scalable, although we will have resource limit imposed to make fair use between different applications. Quota will be documented when we have them.&gt;&gt;<br />
<br />
Before one makes the effort to integrate their data into the Facebook datastore it would be nice to know and understand the limits.&nbsp; Has the quota been documented yet?
  </content>
</rdf:Description>
</rdf:li>

  </rdf:Seq>
</rdf:Description>
</rdf:RDF>
