<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='./OpenSocial.xslt' ?>
<?rfc toc="yes"?>
<?rfc-ext allow-markup-in-artwork="yes"?>
<!DOCTYPE rfc PUBLIC "-//IETF//DTD RFC 2629//EN"
"http://xml.resource.org/authoring/rfc2629.dtd">
<rfc ipr="full3978"
     docName="opensocial-core-data-specification-1-1"
     xmlns:x="http://purl.org/net/xml2rfc/ext">
 <front>
  <title abbrev="Core-Data">OpenSocial Core Data Specification 1.1</title>
  <author fullname='OpenSocial and Gadgets Specification Group'>
   <address>
    <email>opensocial-and-gadgets-spec@googlegroups.com</email>
   </address>
  </author>
  <date month="November"
        year="2010" />
  <abstract>
   <t>This document defines all the data objects used in the <xref target="Core-Gadget"/> and <xref target="Core-API-Server"/> specifications.</t>
  </abstract>
 </front>
 <middle>
  <section title="Notation and Conventions">
   <section title="Requirements">
    <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
    document are to be interpreted as described in 
    <xref target="RFC2119">RFC2119</xref>.</t>
    <t>An implementation is not compliant if it fails to satisfy one or more of
    the MUST or REQUIRED level requirements for the protocols it
    implements.</t>
   </section>
   <section title="Conventions">
    <t>Domain name examples use 
    <xref target="RFC2606">RFC2606</xref>.</t>
   </section>
   <section title="Augmented BNF">
    <t>The grammatical rules in this document are to be interpreted as
    described in <xref target="RFC2234">RFC2234</xref> (Augmented Backus-Naur 
    Form).</t>   
    <t>The following constructs are introduced in this document to augment 
    RFC2234:</t>
    <list style="hanging">
     <t hangText="{rule1 rule2}">
      <t>Elements enclosed in braces (squiggly brackets) are treated as a
      single, UNORDERED element. Its contents may occur in any order. Hence: 
      <artwork type="abnf" xml:space="preserve">{elem foo} bar</artwork>
      would match (elem foo bar) and (foo elem bar).</t>
      <t>NOTE: Specifying alternatives is quite different from specifying set
      grouping. Alternatives indicate the matching of exactly one (sub-)rule
      out of the total grouping. The set mechanism indicates the matching of a
      string which contains all of the elements within the group; however the
      elements may occur in any order.</t>
     </t>
     <t hangText="#rule">A construct "#" is defined, similar to "*", for
     defining lists of elements. The full form is "&lt;n&gt;#&lt;m&gt;element"
     indicating at least &lt;n&gt; and at most &lt;m&gt; elements, each
     separated by one or more commas (",") and OPTIONAL linear white space
     (LWS). This makes the usual form of lists very easy; a rule such as 
     <artwork type="inline" xml:space="preserve">( *LWS element *( *LWS "," *LWS element ))</artwork>
     can be shown as 
     <artwork type="inline" xml:space="preserve">1#element</artwork>
     Wherever this construct is used, null elements are allowed, but do
     not contribute to the count of elements present. That is, "(element), ,
     (element) " is permitted, but counts as only two elements. Therefore, 
     where at least one element is required, at least one non-null element MUST 
     be present.  Default values are 0 and infinity so that "#element" allows 
     any number, including zero; "1#element" requires at least one; and 
     "1#2element" allows one or two.</t>
     <t hangText="&amp;rule">A construct "&amp;" is defined, similar to "#",
     which uses an ampersand (&amp;) instead of commas, and MUST NOT include
     linear white space between elements.</t>
     <t hangText="implied *LWS">The grammar described by this specification is
     word-based. Except where noted otherwise, linear white space (LWS) can be
     included between any two adjacent words (token or quoted-string), and
     between adjacent words and separators, without changing the interpretation
     of a field. At least one delimiter (LWS and/or separators) MUST exist
     between any two tokens, since they would otherwise be interpreted as a
     single token.</t>
    </list>
   </section>
   <section title="Basic Rules">
    <t>The following rules are used throughout this specification to describe
    basic parsing constructs. The US-ASCII coded character set is defined by 
    <xref target="RFC20" /> </t>
    <artwork type="abnf"
         xml:space="preserve">
<![CDATA[
OCTET          = <any 8-bit sequence of data>
CHAR           = <any US-ASCII character (octets 0 - 127)>
UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
LOALPHA        = <any US-ASCII lowercase letter "a".."z">
ALPHA          = UPALPHA / LOALPHA
DIGIT          = <any US-ASCII digit "0".."9">
CTL            = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>
<">            = <US-ASCII double-quote mark (34)>
CRLF           = CR LF
LWS            = [CRLF] 1*( SP / HT )
TEXT           = <any OCTET except CTLs, but including LWS>
COMMA          = <US-ASCII comma (44)>
      ]]>
</artwork>
   </section>
  </section>
  <section title="Data"
           anchor="data">
   <section title="Array" anchor="Array">
     <t>An Array is represented as a comma separated list of values, surrounded by square brackets.</t>
    <artwork type="abnf"
         xml:space="preserve">
Array&lt;Object&gt; = "[" #Object "]"
</artwork>
   </section>
   <section title="Boolean" anchor="Boolean">
    <artwork type="abnf"
         xml:space="preserve">
Boolean = "true" / "false"
</artwork>
   </section>
   <section title="Collection"
            anchor="Collection">
    <t>Many service operations return a list of OpenSocial resources. Lists are
    always returned in the "list" field of the result. Lists can either be the
    full set of resources or a pageable subset. If the operation supports
    random access indexing of the full list it will support the "startIndex"
    and "count" parameters which control what sublist of the full list is
    returned. The paging mechanisms described here are based on the OpenSearch
    standard with the additional requirement that all indexes are 0 based.</t>
    <artwork type="abnf"
         xml:space="preserve">
Collection = "{"
               "result : {"
                  [ "totalResults : " number "," ]
                  [ "startIndex : " number "," ]
                  [ "itemsPerPage : " number "," ]
                  [ "filtered : " ( "true" / "false" ) "," ]
                  [ "updatedSince : " ( "true" / "false" ) "," ]
                  [ "sorted : " ( "true" / "false" ) "," ]
                  [ "itemsPerPage : " number "," ]
                  "entry :" Array&lt;Object&gt; 
                "}"
              "}"
</artwork>
     <texttable>
      <ttcol align="left" width="10%">Field Name</ttcol>
      <ttcol align="left" width="15%">Field Type</ttcol>
      <ttcol align="left">Description</ttcol>
      <c>startIndex</c>
      <c>number</c>
      <c>The index of the first result returned in this response,
      relative to the starting index of all results that would be returned if
      no startIndex had been requested. In general, this will be equal to the
      value requested by the startIndex, or 0 if no specific startIndex was
      requested.</c>
      <c>itemsPerPage</c>
      <c>number</c>
      <c>The number of results returned per page in this
      response. In general, this will be equal to the count Query Parameter,
      but MAY be less if the Service Provider is unwilling to return as many
      results per page as requested, or if there are less than the requested
      number of results left to return when starting at the current startIndex.
      This field MUST be present if and only if a value for count is specified
      in the request.</c>
      <c>totalResults</c>
      <c>number</c>
      <c>The total number of contacts that would be returned if
      there were no startIndex or count specified. This value tells the
      Consumer how many total results to expect, regardless of the current
      pagination being used, but taking into account the current filtering
      options in the request.</c>
      <c>entry</c>
      <c><x:ref>Array</x:ref>&lt;Object&gt;</c>
      <c>An array of objects, one for each item matching the request. 
      For consistency of parsing, if the
      request could possibly return multiple items (as is normally the case),
      this value MUST always be an array of results, even if there
      happens to be
      0 or 1 matching results. (i.e. "entry": [ { /* first item */ },
      { /* seond item */ } ]).</c>
      <c>filtered</c>
      <c><x:ref>Boolean</x:ref></c>
      <c>indicating if the result honors filter params in the
      request. The default value is 'true' if the field does not
      exist.</c>
      <c>sorted</c>
      <c><x:ref>Boolean</x:ref></c>
      <c>Indicating if the items are sorted. The default value is
      'true' if the field does not exist.</c>
      <c>updatedSince</c>
      <c><x:ref>Boolean</x:ref></c>
      <c>Indicating if the result honors the updatedSince  param in
      the request. The default value is 'true' if the field does not
      exist.</c>
     </texttable>
   </section>
   <section title="Date" anchor="Date">
     <t>See: <xref target="XSdateTime">XML Schema dateTime format</xref></t>
     <t>Example: 2008-01-23T04:56:22Z</t>
   </section>
   <section title="Date-UTC-Offset" anchor="Date-UTC-Offset">
     <t>See: <xref target="XSdateTime">XML Schema dateTime format, offset portion</xref></t>
     <t>Example: -08:00</t>
   </section>
   <section title="Domain-Name" anchor="Domain-Name">
     <t>The Domain-Name is an optional data type that containers may
     use to uniquely identify themselves. It is recommended that they
     use a registered domain name where possible.</t>
    <artwork type="abnf"
         xml:space="preserve">
Domain-Name = *( ALPHA / DIGIT / "_" / "." / "-" )
</artwork>
   </section>
   <section title="Global-Id" anchor="Global-Id">
     <t>The Global-Id is an optional data type designed to allow
     scoping of ids across domains. Global-Ids are identified by
     containing a semi-colon (:) as part of the id itself. If a
     containers supports the Global-Id, all API calls MUST support the
     Global-Id for queries, the returned data may optionally use
     Global-Ids. It is the responsibility of the consumer to verify
     the type of returned Id is appropriate for their usage, and to
     convert any Local-Ids to Global-Ids as needed.</t>
    <artwork type="abnf"
         xml:space="preserve">
Global-Id   = <x:ref>Domain-Name</x:ref> ":" <x:ref>Local-Id</x:ref>
</artwork>
   </section>
   <section title="HTTP-Request-Params" anchor="HTTP-Request-Params">
     <t>Requests to arbitrary URLs use the following parameters:</t>
     <texttable align="left">
      <ttcol>Name</ttcol>
      <ttcol>Type</ttcol>
      <ttcol>Description</ttcol>
      <c>authz</c>
      <c>String</c>
      <c>Indicates the authorization method to use when sending data to the remote server.  Must be one of "none", "signed", or "oauth". Defaults to "none".</c>
      <c>format</c>
      <c>String</c>
      <c>Format data is returned in for processing, values are "json" or "text". Defaults to "json". Optional</c>
      <c>headers</c>
      <c>Map&lt;String, <eref target="Core-Data.xml#Array">Array</eref>&lt;String&gt;&gt;</c>
      <c>Additional HTTP headers to include in the request. Optional.</c>
      <c>href</c>
      <c>String</c>
      <c>The URL to send the request to. Required.</c>
      <c>oauth_service_name</c>
      <c>String</c>
      <c>Identifies the service element in the gadget spec to use for this request.  Defaults to an empty string.</c>
      <c>oauth_request_token</c>
      <c>String</c>
      <c>A token that is pre-approved by the provider for access to the resource. Optional.</c>
      <c>oauth_request_token_secret</c>
      <c>String</c>
      <c>Secret associated with the pre-approved request token. Optional.</c>
      <c>oauth_token_name</c>
      <c>String</c>
      <c>Identifies the OAuth token used to make a request to the service provider. Defaults to an empty string.</c>
      <c>oauth_use_token</c>
      <c>String</c>
      <c>Controls whether an OAuth token should be used with the request. Allowed values are "always", "if_available", and "never". Optional.</c>
      <c>refreshInterval</c>
      <c>number</c>
      <c>Number of seconds for which the container can cache the data. If this parameter is set, it overrides the HTTP response header sent back from the HTTP request. Optional.</c>
      <c>sign_owner</c>
      <c><eref target="Core-Data.xml#Boolean">Boolean</eref></c>
      <c>Indicates if the current viewer's ID should be included in the request signature. Defaults to "true".</c>
      <c>sign_viewer</c>
      <c><eref target="Core-Data.xml#Boolean">Boolean</eref></c>
      <c>Indicates if the current viewer's ID should be included in the request signature. Defaults to "true".</c>
     </texttable>
   </section>
   <section title="HTTP-Response-Payload">
     <t>When a container makes an HTTP request on behalf of a gadget (e.g. osapi.http.get(), or &lt;os:HttpRequest&gt;) the response will contain the following properties:</t>
     <texttable align="left">
      <ttcol>Name</ttcol>
      <ttcol>Type</ttcol>
      <ttcol>Description</ttcol>
      <c>content</c>
      <c>String / Object</c>
      <c>If @format is "text", the string content of the
response. If @format is "json", the parsed JSON object or array of the
response. If a JSON response cannot be parsed, a 406 (Not Acceptable) error
code will be produced.</c>
      <c>headers</c>
      <c>Map&lt;String, <eref target="Core-Data.xml#Array">Array</eref>&lt;String&gt;&gt;</c>
      <c>An map with response header names as keys,
and the header values as per-key arrays.</c>
      <c>status</c>
      <c>number</c>
      <c>The HTTP status code.</c>
     </texttable>
   </section>
   <section title="Local-Id" anchor="Local-Id">
    <artwork type="abnf"
         xml:space="preserve">
Local-Id = *( ALPHA / DIGIT / "_" / "." / "-" )
</artwork>
   </section>
   <section title="Object-Id" anchor="Object-Id">
     <t>Object-Id is to be an opaque string value that the API will
     use for resultant data and for queries. Containers MUST support
     for any query, and valid id that the API returns. Containers MAY
     support the Global-Id format.</t>
    <artwork type="abnf"
         xml:space="preserve">
Object-Id = <x:ref>Local-Id</x:ref> / <x:ref>Global-Id</x:ref>
</artwork>
   </section>
   <section title="Plural-Field" anchor="Plural-Field">
     <texttable>
      <ttcol align="left" width="10%">Field Name</ttcol>
      <ttcol align="left" width="15%">Field Type</ttcol>
      <ttcol align="left">Description</ttcol>
      <c>value</c>
      <c><x:ref>Object</x:ref></c>
      <c>The primary value of this field, e.g. the actual e-mail address, phone
      number, or URL. When specifying a sortBy field in the Query Parameters for
      a Plural Field, the default meaning is to sort based on this value
      sub-field. Each non-empty Plural Field value MUST contain at least the
      value sub-field, but all other sub-fields are optional.</c>
      <c>type</c>
      <c>string</c>
      <c>The type of field for this instance, usually used to label the
      preferred function of the given contact information. Unless otherwise
      specified, this string value specifies Canonical Values of work, home,
      and other.</c>
      <c>primary</c>
      <c><x:ref>Boolean</x:ref></c>
      <c>A Boolean value indicating whether this instance of the Plural Field
      is the primary or preferred value of for this field, e.g. the preferred
      mailing address or primary e-mail address. Service Providers MUST NOT
      mark more than one instance of the same Plural Field as primary="true",
      and MAY choose not to mark any fields as primary, if this information is
      not available. For efficiency, Service Providers SHOULD NOT mark all
      non-primary fields with primary="false", but should instead omit this
      sub-field for all non-primary instances.</c>
     </texttable>
     <t>When returning Plural Fields, Service Providers SHOULD canonicalize the
     value returned, if appropriate (e.g. for e-mail addresses and URLs).
     Providers MAY return the same value more than once with different types
     (e.g. the same e-mail address may used for work and home), but SHOULD NOT
     return the same (type, value) combination more than once per Plural Field,
     as this complicates processing by the Consumer.</t>
   </section>
   <section title="User-Id" anchor="User-Id">
     <t>A User-Id uses the same format as an <x:ref>Object-Id</x:ref>, but there are several reserved values for common cases.</t>
     <artwork type="abnf"
         xml:space="preserve">
User-Id = <x:ref>Object-Id</x:ref> / "@owner" / "@viewer" / "@me"
</artwork>
     <t>The reserved values are defined in the following table:</t>
     <texttable align="left">
       <ttcol>Value</ttcol>
       <ttcol>Description</ttcol>
       <c>@owner</c>
       <c>The user that owns the current page.  For example, if Alice is viewing Bob's profile page, then Bob is the owner.</c>
       <c>@viewer</c>
       <c>The user than is logged in an viewing the current page. For example, if Alice is viewing Bob's profile page, then Alice is the viewer.</c>
       <c>@me</c>
       <c>The currently authenticated user. For example, when an API request is received the user who's credentials are included in the authorization header of the request can be referenced as '@me'.</c>
     </texttable>
   </section>
  </section>
  <section title="Data Representations" anchor="Data-Representations">
   <t>Each resource has three representations, as JSON, XML, and Atom. All data
   must be representable in each format. The XML and JSON formats have a one to
   one mapping while the Atom format is defined separately for each type of
   object and collection. Throughout this document, examples are only given
   in JSON and Atom. The XML representation can be mapped directly from the
   JSON and MUST conform to the XSD provided for each data type.</t>
   <t>Each resource is represented as a hierarchical tree of elements. Ordering
   of elements within a parent element may or may not be significant, depending
   on the context. Mapping consists of converting between the internal
   hierarchy and the JSON/XML or Atom protocol format.</t>
   <t>The general rules for mapping between the Atom and JSON formats are as
   follows. Each data type may add additional aliasing rules. 
   <list style="symbols">
    <t>The default location for all data in the Atom format is in
    atom:entry/atom:content/datatype, where datatype is a root node naming the
    type of data delivered: &lt;person&gt;, &lt;group&gt;, &lt;activity&gt;, or
    &lt;appdata&gt;.</t>
    <t>The field names are specified at the end of this document in
    camelCase.</t>
    <t>Strings are represented as strings in both formats.</t>
    <t>Dates and timestamps are represented as strings using 
    <xref target="RFC3339">RFC3339 Timestamps</xref> format date-time elements.
    These are also known as "XSD Dates". In cases where only a day-of-the-year
    is desired, e.g., a birthday, the year SHOULD be specified as 0000.</t>
    <t>Enums are represented as objects with "displayvalue" (localizable,
    customizable string) and "key" (key) fields.</t>
    <t>Arrays are represented as arrays in the JSON representation and as
    repeated fields in the XML representation.</t>
    <t>Sub-objects are represented as sub-elements in both formats.</t>
    <t>Fields are placed directly in the root object in the JSON format. In the
    Atom format, they are by default placed under atom:content/datatype (e.g.,
    atom:content/person for person data). Some fields are 'hoisted' and aliased
    to standard Atom fields directly underneath atom:entry. There are three
    standard aliases that apply to all data types: 
    <list style="symbols">
     <t>atom:entry/atom:id aliases the "id" field. The JSON format id is the
     OpenSocial globally unique ID, which consists of the container domain
     (e.g., example.org) followed by a colon and the container's id for that
     person. The container specific id can only contain letters (A-Za-z),
     numbers (0-9), dots (.), hyphens (-) and underscores (_). For example,
     example.org:78gh37261ddfdf. In the Atom format, it is translated into the
     required URI data type by prepending "urn:guid:" to the OpenSocial ID
     string. These rules are intended to make mapping IDs between the RESTful
     API and the JS API straightforward while preserving global uniqueness.</t>
     <t>atom:entry/atom:updated aliases the JSON field indicating the most
     recent update time if available (POSTED_TIME for Activity), or the
     generation time if no better information is available.</t>
     <t>atom:entry/atom:published aliases the JSON field indicating creation
     time (POSTED_TIME for Activity).</t>
    </list></t>
   </list></t>
   <section title="Rules for mapping JSON to XML"
           anchor="JSON-to-XML">
   <t>Singular fields are encoded as string key/value pairs in JSON and tags
   with text content in XML, e.g. "field": "value" and
   &lt;field&gt;value&lt;/field&gt; respectively.</t>
   <t>Plural fields are encoded as arrays in JSON and repeated tags in XML,
   e.g. "fields": [ "value1", "value2" ] and
   &lt;field&gt;value1&lt;/field&gt;&lt;field&gt;value2&lt;/field&gt;
   respectively.</t>
   <t>Nodes with multiple sub-nodes are represented as objects in JSON and tags
   with sub-tags in XML, e.g. "field": { "subfield1": "value1", "subfield2":
   "value2" } and
   &lt;field&gt;&lt;subfield1&gt;value1&lt;/subfield1&gt;&lt;subfield2&gt;value2&lt;/subfield2&gt;&lt;/field&gt;
   respectively.</t>
   </section>
  </section>
 </middle>
 <back>
  <references>
   <reference anchor='RFC2119'>
    <front>
     <title>Key words for use in RFCs to Indicate Requirement Levels</title>
     <author initials='S.'
             surname='Bradner'
             fullname='Scott Bradner'>
      <organization abbrev='HarvardU'>Harvard University</organization>
     </author>
     <date month='March'
           year='1997' />
    </front>
    <seriesInfo name='RFC' value='2119' />
   </reference>
   <reference anchor='RFC2606'>
    <front>
     <title>Reserved Top Level DNS Names</title>
     <author initials='D.'
             surname='Eastlake'
             fullname='Donald E. Eastlake 3rd'>
      <organization abbrev='IBM'>IBM</organization>
     </author>
     <author initials='A.'
             surname='Panitz'
             fullname='Aliza R. Panitz'></author>
     <date month='June'
           year='1999' />
    </front>
    <seriesInfo name='RFC'
                value='2606' />
   </reference>
   <reference anchor='RFC2234'>
    <front>
     <title>Augmented BNF for Syntax Specifications: ABNF</title>
    </front>
    <seriesInfo name='RFC'
                value='2234' />
   </reference>
   <reference anchor='RFC3339'>
    <front>
     <title>Date and Time on the Internet: Timestamps</title>
    </front>
    <seriesInfo name='RFC'
                value='3339' />
   </reference>
   <reference anchor='RFC20'>
    <front>
     <title>ASCII format for Network Interchange</title>
    </front>
    <seriesInfo name='RFC'
                value='20' />
   </reference>
   <reference anchor="XSdateTime"
              target="http://www.w3.org/TR/xmlschema-2/#dateTime">
    <front>
     <title>XML Schema Part 2: Datatypes Second Edition</title>
     <author initials='P.V.'
             surname='Biron'
             fullname='Paul V. Biron'>
      <organization>Kaiser Permanente, for Health Level Seven</organization>
     </author>
     <author initials='A.'
             surname='Malhotra'
             fullname='Ashok Malhotra'>
      <organization>Microsoft</organization>
     </author>
     <date month='October'
           year='2004' />
    </front>
   </reference>
   <reference anchor="Core-Gadget"
              target="./Core-Gadget.xml">
    <front>
     <title>OpenSocial Core Gadget Specification</title>
     <author fullname='OpenSocial and Gadgets Specification Group &lt;opensocial-and-gadgets-spec@googlegroups.com&gt;'>
     </author>
     <date month='November'
           year='2010' />
    </front>
   </reference>
   <reference anchor="Core-API-Server"
              target="./Core-API-Server.xml">
    <front>
     <title>OpenSocial Core API Server Specification</title>
     <author fullname='OpenSocial and Gadgets Specification Group &lt;opensocial-and-gadgets-spec@googlegroups.com&gt;'>
     </author>
     <date month='November'
           year='2010' />
    </front>
   </reference>
  </references>
 </back>
</rfc>

