<?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-2-5-1"
     xmlns:x="http://purl.org/net/xml2rfc/ext">
 <front>
  <title abbrev="Core-Data">OpenSocial Core Data Specification 2.5.1</title>
  <author fullname='OpenSocial and Gadgets Specification Group'>
   <address>
    <email>opensocial-and-gadgets-spec@googlegroups.com</email>
   </address>
  </author>
<date month="August" year="2013" />
  <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>
	
	  <t>The Collection data type will have metadata information that provides information
    about the data returned.</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 "," ]
                  "list :" 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.
      </c>
      <c>totalResults</c>
      <c>number</c>
      <c>The total number of data 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>list</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. "list": [ { /* 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>
     <xref target='Issue-1323'>Discussion</xref>
   </section>
   <section title="Activity Streams Support" anchor="ActivityStreamsCollection"><xref target='Issue-1140'>Discussion</xref>
           <t>OpenSocial 2.0 has incorporated support for the Activity Streams community specification. This specification
           also defines a collection structure. In order to maintain compatibility with endpoints that expect an
           Activity Streams collection definition, OpenSocial containers SHOULD append the additional fields onto
           collection structures that are returned from the ActivityStreams service.</t>

           <t>Note: The OpenSocial specification declares that extensions should be wrapped in "tags" that "namespace" the
           extended fields. This is done primarily to avoid collisions. However, an endpoint that is configured to
           receive an Activity Stream collection would not expect collection fields to be wrapped. Therefore, in order
           to support interoperability, an exception has been made for OpenSocial Collection. Fields from Activity
           Streams Collection SHOULD be appended directly to OpenSocial Collection.</t>
   </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="Mapping Global Id to an IRI" anchor="IRI-Mapping">
   <xref target='Issue-1140'>Discussion</xref>
         <t>There are several external systems and specifications that leverage the use of IRI as the way to uniquely and
         globally identify an object. Activity Streams is an example of one such specification. OpenSocial's uses a
         slightly different format for uniquely identifying objects. To support interoperability with other containers
         as well as Activity Stream endpoints, OpenSocial 2.0 introduces an alternate format for uniquely identifying
         its objects that is based upon the IRI scheme.</t>

         <t>IRI is an acronym for "Internationalized Resource Identifier". It has a structure similar to a URL. From the
         perspective of OpenSocial, the objective is to easily map the components of Global Id into an IRI that may be
         used to access the resource, e.g. via REST endpoints. To create an IRI, the following pattern should be used:</t>
		<list style="symbols">
         <t>Global Id will map to the IRI iauthority.</t>
         <t>Local Id will include an IRI ipath-absolute that represents the OpenSocial service, plus an IRI ipath-rootless
         that contains the Local-Id.</t>
        </list>

         <t>An example of this mapping is as follows. Let's assume that we have an OpenSocial based container named
         "MySocial". It's domain is "MySocial.com". Each user is given a unique user Id, e.g. 1234. The OpenSocial
         Object Id is: MySocial.com:1234</t>

         <t>To construct an IRI from the Global Id using the mapping above, the result would be:
         https://MySocial.com/people/1234</t>

         <t>IRI that are created MUST conform to the patterns defined in the OpenSocial Core API Server specification. It
         is RECOMMENDED that they conform to Section 2.1, REST. The ipath-absolute SHOULD be an OpenSocial service as
         defined in the Social API Server specification. However, this is not mandated because it is the intent that the
         programming model defined by this specification be extended. Therefore, new services may be added outside of a
         specification cycle, e.g. incubating, or as a domain specific service. In the situation where a service is use
         that is NOT defined by the OpenSocial specification, it is RECOMMENDED that a definition of that service be
         publicly available via the Internet. Where an IRI is used in the specification, as in the Activity Streams,
         containers MUST support this alternate form of Global ID. Containers SHOULD use this alternate form of Global
         ID as a replacement for Global ID.</t>
   </section>

   <section title="HTTP-Request-Params" anchor="HTTP-Request-Params">
      
     <t>Readers of this section should also review the Security section in the
        Core API Server specification as well as the OAuth information
        documented in the Core Gadget Specfication. The reader should also
        be familiar with the OAuth specification (1.0A or 2.0).</t>
     <xref target='Issue-1138'>Discussion</xref>
     <t>The parameters described in this section are set by the gadget running in 
        the Core Container and are passed
        to the Core Gadget Server so that it will appropriately process the request.</t>
     <t>If a gadget is using a Core Gadget Server to proxy requests to a remote server
        then none of the OAuth parmeters documented here are necessary and they
        should not be used.</t>
     <t>The http parmaeters for OAuth documented here are used in cases where
        a gadget is running in Javascript only (or similar) environments
        (called an implicit grant in OAuth speak).  In these scenarios, a gadget does
        not have a Core Gadget Server that stores token information.  In these 
        scenarios, a gadget talks directly to the remote server it wants to obtain
        data from.  When operating in a Javascript only environment, or those with
        similar characteristics, some of the documented request parameters 
        will be needed.</t>
     <t>Requests to arbitrary URLs use the following parameters:</t>
     <texttable align="left">
      <ttcol>Name</ttcol>
      <ttcol>Type</ttcol>
      <ttcol>Description</ttcol>
       <c>alias</c>
       <c>String</c>
       <c>The external service name, defined by the application developer, as part of the module preferences. This
             will indicated to the container which external service tag to use. <xref target='Issue-1178'>Discussion</xref>
       </c>
       <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", "oauth" or "oauth2". Defaults to "none". <xref target='Issue-1138'>Discussion</xref></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>Gadget XML can define more than one "clause" that represents an end point protected by OAuth
      	  that the gadget accesses.
      	  This parameter identifies the "service element" or "xml nickname" in the gadget XML
      	  that identifies the OAuth information to be used for this specific request.
      	  Defaults to an empty string.  
      	  ** Not sure when this would ever be used.  In proxied requests, this is unnecessary
      	  because the information about a service element is passed on the makeRequest call.
      	  In a Javascript-like environment, the gadget will not refer to its own XML specification
      	  but will simply supply the correct token and URI.  This parameter is optional.</c>
      <c>oauth_request_token</c>
      <c>String</c>
      <c>This parameter uses OAuth 1.0a terminology but is also used for OAuth 2 scenarios.
          This is an access token that is pre-approved by the provider for access to the 
          resource. When calls are proxied by the Core Gadget Server, the gadget should not
          have direct access to oauth tokens so this parameter will not be used.
          This parmaeter is optional.</c>
      <c>oauth_request_token_secret</c>
      <c>String</c>
      <c>Secret associated with the pre-approved request token.  This parameter
          is left here for legacy reasons and MUST never be used.  Gadgets cannot
          secure secrets in the browser and therefore should never hold secrets.
          The OAuth 2 security considerations clearly outline that for browser
          based software, secrets should not be issued. For proxied requests,
          the secrets are held by the Core Gadget Server and are passed by
          the server on the proxied call.  This parmaeter is 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.
         For proxied requests, the token name is passed in the optional parameters to the makeRequest API call
         so this parameter is unnecessary.
         ** Not sure when this would ever be used.  In a Javascript only situation, a gadget won't need
         to use the indirection associated with passing a token name, but will pass the access token
         directly on the call.</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". This parameter is optional.
         **Not sure why this would ever be used.  If other OAuth parameters are passed and if
         the authz parameter is set to "oauth" or "oauth2" then it is clear that OAuth should be used.
         If those other parmeters are missing, then OAuth won't be used.'</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" anchor="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>
      <c>
      label
      </c>
      <c>String</c>
      <c>
      <x:incubating href="http://code.google.com/p/opensocial-resources/issues/detail?id=1282" note="Issue 1282 - Add label to plural fields">
      Provides a human-readable, plain-text, and preferrably localized short description of the object value suitable for display to a user.
      </x:incubating> 
      </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">
   <x:deprecated note="ATOM Support" href="http://code.google.com/p/opensocial-resources/issues/detail?id=1152">
   <t>Support for the ATOM format is being deprecated in the OpenSocial 2.0 release.  Consumers should start migrating to using JSON or XML representations.</t>
   </x:deprecated>
   <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 title="Discussion">
    <!-- Spec change issues/discussion -->
   <reference anchor='Issue-1140'
              target="http://code.google.com/p/opensocial-resources/issues/detail?id=1140">
    <front>
     <title>Incorporate ActivityStreams 1.0 into OpenSocial</title>
    </front>
   </reference>
   <reference anchor='Issue-1178'
              target="http://code.google.com/p/opensocial-resources/issues/detail?id=1178">
    <front>
     <title>Add 'alias' to HTTP Request</title>
    </front>
   </reference>
   <reference anchor='Issue-1138'
              target="http://code.google.com/p/opensocial-resources/issues/detail?id=1138">
    <front>
     <title>OAuth 2.0 Support</title>
    </front>
   </reference>
   <reference anchor='Issue-1323'
              target="http://code.google.com/p/opensocial-resources/issues/detail?id=1323">
    <front>
     <title>Missing the specifications for metadata information for Collections data type for JSON-RPC and REST endpoints</title>
    </front>
   </reference>
 </references>
  <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='August'
           year='2011' />
    </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='August'
           year='2011' />
    </front>
   </reference>
  </references>
 </back>
</rfc>

