xeps/xep-0099.xml

402 строки
14 KiB
XML

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM "xep.ent">
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>IQ Query Action Protocol</title>
<abstract>Standardizes behavior of &IQ; &QUERY; actions for generic query behavior.</abstract>
&LEGALNOTICE;
<number>0099</number>
<status>Deferred</status>
<type>Standards Track</type>
<sig>Standards</sig>
<dependencies/>
<supersedes/>
<supersededby/>
<shortname>Not yet assigned</shortname>
<author>
<firstname>Iain</firstname>
<surname>Shigeoka</surname>
<email>iain@jivesoftware.com</email>
<jid>smirk@jabber.com</jid>
</author>
<revision>
<version>0.1.1</version>
<date>2018-11-03</date>
<initials>pep</initials>
<remark>Fix a bunch of typos, batch-style.</remark>
</revision>
<revision>
<version>0.1</version>
<date>2003-06-25</date>
<initials>iss</initials>
<remark>Initial version.</remark>
</revision>
</header>
<section1 topic='Introduction'>
<p>There is a need for consistent query behavior amongst XMPP &IQ; protocols. Currently
each protocol invents its own, slightly different behavior for conducting
query behavior to create, read, update, and delete (CRUD) recipient node data. This document defines a generic
query acton protocol to standardize behavior across &IQ; protocols. In addition, we hope
this standard will make other protocols easier to understand and implement by using a common
core protocol.</p>
</section1>
<section1 topic='&QUERY; Action Protocol'>
<section2 topic='Description'>
<p>The existing XMPP core protocol defines
four &IQ; types (get, set, result, and error). Unfortunately, these
four types don't include a 'delete' type, and the 'set' type must do double duty for
'create' and 'update'. Many protocols can benefit from a clear separation of create
and update paralleling other query languages such as SQL.</p>
<p>Protocols complying with the &QUERY; action protocol use &IQ; 'set' to initiate
all request-response interactions. The particular action to be taken MUST be set as an "action" attribute
in the &IQ; &QUERY; sub-element. The action attribute MUST have a value of 'create', 'read',
'update', or 'delete'. Responses use the standard &IQ; 'result' and 'error' types.
For backward compatibility, an &IQ; 'get' query is treated as equivalent to an &IQ; 'set'
query with action of 'read'. Action protocols may require all or just a subset of these
actions depending on the desired outcome.</p>
<p>In addition to the action attribute an optional "strict" attribute may be set in the &IQ; &QUERY;
sub-element. The only valid values for strict is "true" or "false" (case sensitive).
The strict behavior of actions causes more errors to be returned which tends to make
protocols more robust but also more complex. Action protocols MUST define the default value of
the "strict" attribute in the context of that protocol. In addition, some protocols may
not wish to allow changing the strict default, so action protocols MUST declare
whether the strict behavior of the protocol may be set in the &IQ; &QUERY; sub-element.</p>
</section2>
<section2 topic='Actions'>
<table caption='Description of Acceptable &QUERY; Actions'>
<tr><td>create</td><td>Creates/inserts new data on the recipient node.</td></tr>
<tr><td>read</td><td>Retrieves data from the recipient node.</td></tr>
<tr><td>update</td><td>Updates existing data on the recipient node.</td></tr>
<tr><td>delete</td><td>Deletes existing data on the recipient node.</td></tr>
</table>
</section2>
<section2 topic='Elements'>
<p>The root element is query which is in a namespace defining the
protocol in use. The query element MUST have
an attribute named 'action' with values given in the previous table.</p>
</section2>
<section2 topic='Error Codes'>
<p>The following error codes apply to all action codes.</p>
<table caption='Error Codes used by Action Protocols'>
<tr>
<th>Code</th><th>Text</th><th>Description</th>
</tr>
<tr>
<td>406</td><td>Not Acceptable</td><td>The IQ query contents are not properly formatted for the action protocol.</td>
</tr>
<tr>
<td>503</td><td>Service Unavailable</td><td>The IQ query is sent to a JID that cannot handle the query.</td>
</tr>
</table>
</section2>
</section1>
<section1 topic='Create Action'>
<section2 topic='Description'>
<p>The create action inserts new data on the recipient node. If the strict attribute is
'true' the create action fails if colliding data already exists on the recipient node. If the strict
attribute is false, the create action will insert new data on the recipient node overwriting
existing colliding data if it exists (e.g. equivalent to update).</p>
</section2>
<section2 topic='Error Codes'>
<table caption='Error Codes used by Create Action'>
<tr>
<th>Code</th><th>Text</th><th>Description</th>
</tr>
<tr>
<td>409</td><td>Conflict</td><td>The strict attribute is set to 'true' and colliding data exists on the recipient node.</td>
</tr>
</table>
</section2>
<section2 topic='Examples'>
<p>Creating new data on the server using iq:private, and strict actions when no existing data is on the server.</p>
<example caption='Client Stores New Private Data'><![CDATA[
SENDER:
<iq type="set" id="1001">
<query xmlns="jabber:iq:private" action="create" strict="true">
<exodus xmlns="exodus:prefs">
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
RECIPIENT:
<iq
type="result"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1001"/>
]]></example>
<p>With strict actions enabled, conflict data will cause the create action
to fail when existing data is on the recipient node. Here we show iq:private, and strict actions with existing data on the server.</p>
<example caption='Client Stores New Private Data but Conflicts'><![CDATA[
SENDER:
<iq type="set" id="1002">
<query xmlns="jabber:iq:private" action="create" strict="true">
<exodus xmlns="exodus:prefs">
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
RECIPIENT:
<iq
type="error"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1002">
<error code="409">Conflict</error>
<exodus xmlns="exodus:prefs">
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
]]></example>
</section2>
</section1>
<section1 topic='Read Action'>
<section2 topic='Description'>
<p>The read action retrieves data on the recipient node. If the strict attribute is
'true' the read action fails if no appropriate data exists on the recipient node. If the strict
attribute is false, the read action will always return with a 'result', sending an empty
result in place of a 'not found' error.</p>
</section2>
<section2 topic='Error Codes'>
<table caption='Error Codes used by Create Action'>
<tr>
<th>Code</th><th>Text</th><th>Description</th>
</tr>
<tr>
<td>404</td><td>Not found</td><td>The strict attribute is set to 'true' and no matching data exists on the recipient node.</td>
</tr>
</table>
</section2>
<section2 topic='Examples'>
<p>Reading data on the server using iq:private, and strict actions when data is on the server.</p>
<example caption='Client Reads Private Data'><![CDATA[
SENDER:
<iq type="set" id="1001">
<query xmlns="jabber:iq:private" action="read" strict="true">
<exodus xmlns="exodus:prefs"/>
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
RECIPIENT:
<iq
type="result"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1001">
<query xmlns="jabber:iq:private" action="read" strict="true">
<exodus xmlns="exodus:prefs"/>
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
]]></example>
<p>With strict actions enabled, the absence of matching data will cause the read action
to fail. Here we show iq:private, and strict actions with no matching data on the server.</p>
<example caption='Client Reads Private Data but Not Found (strict)'><![CDATA[
SENDER:
<iq type="set" id="1002">
<query xmlns="jabber:iq:private" action="read" strict="true">
<data xmlns="imaginary"/>
</query>
</iq>
RECIPIENT:
<iq
type="error"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1002">
<error code="404">Not Found</error>
<data xmlns="imaginary"/>
</query>
</iq>
]]></example>
<p>With strict actions disabled, the absence of matching data will cause the read action
to return an 'empty' result. Here we show iq:private, and strict actions disabled with no matching data
on the server.</p>
<example caption='Client Reads Private Data but Not Found (not strict)'><![CDATA[
SENDER:
<iq type="set" id="1003">
<query xmlns="jabber:iq:private" action="read" strict="false">
<data xmlns="imaginary"/>
</query>
</iq>
RECIPIENT:
<iq
type="result"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1003">
<data xmlns="imaginary"/>
</query>
</iq>
]]></example>
</section2>
</section1>
<section1 topic='Update Action'>
<section2 topic='Description'>
<p>The update action edits existing data on the recipient node. If the strict attribute is
'true' the update action fails if matching data does not already exists on the recipient node. If the strict
attribute is false, the update action will edit existing data, inserting the data on the recipient node
if necessary.</p>
</section2>
<section2 topic='Error Codes'>
<table caption='Error Codes used by Create Action'>
<tr>
<th>Code</th><th>Text</th><th>Description</th>
</tr>
<tr>
<td>404</td><td>Not Found</td><td>The strict attribute is set to 'true' and matching data does NOT already exist on the recipient node.</td>
</tr>
</table>
</section2>
<section2 topic='Examples'>
<p>Updating existing new data on the server using iq:private, and strict actions when existing data is on the server.</p>
<example caption='Client Updates Existing Private Data'><![CDATA[
SENDER:
<iq type="set" id="1001">
<query xmlns="jabber:iq:private" action="update" strict="true">
<exodus xmlns="exodus:prefs">
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
RECIPIENT:
<iq
type="result"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1001"/>
]]></example>
<p>With strict actions enabled, the absence of existing data will cause the update action
to fail. Here we show iq:private, and strict actions with no existing data on the server.</p>
<example caption='Client Updates Private Data but None Found'><![CDATA[
SENDER:
<iq type="set" id="1002">
<query xmlns="jabber:iq:private" action="update" strict="true">
<exodus xmlns="exodus:prefs">
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
RECIPIENT:
<iq
type="error"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1002">
<error code="404">Not Found</error>
<exodus xmlns="exodus:prefs">
<defaultnick>Hamlet</defaultnick>
</exodus>
</query>
</iq>
]]></example>
</section2>
</section1>
<section1 topic='Delete Action'>
<section2 topic='Description'>
<p>The delete action deletes existing data on the recipient node. If the strict attribute is
'true' the delete action fails if matching data does not already exists on the recipient node. If the strict
attribute is false, the delete action will delete any existing data on the recipient node (if any) and return
successful..</p>
</section2>
<section2 topic='Error Codes'>
<table caption='Error Codes used by Create Action'>
<tr>
<th>Code</th><th>Text</th><th>Description</th>
</tr>
<tr>
<td>404</td><td>Not Found</td><td>The strict attribute is set to 'true' and matching data does NOT already exist on the recipient node.</td>
</tr>
</table>
</section2>
<section2 topic='Examples'>
<p>Deleting existing new data on the server using iq:private, and strict actions when existing data is on the server.</p>
<example caption='Client Deletes Existing Private Data'><![CDATA[
SENDER:
<iq type="set" id="1001">
<query xmlns="jabber:iq:private" action="delete" strict="true">
<exodus xmlns="exodus:prefs"/>
</query>
</iq>
RECIPIENT:
<iq
type="result"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1001"/>
]]></example>
<p>With strict actions enabled, the absence of existing data will cause the delete action
to fail. Here we show iq:private, and strict actions with no existing data on the server.</p>
<example caption='Client Deletes Private Data but None Found (strict)'><![CDATA[
SENDER:
<iq type="set" id="1002">
<query xmlns="jabber:iq:private" action="delete" strict="true">
<data xmlns="imaginary"/>
</query>
</iq>
RECIPIENT:
<iq
type="error"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1002">
<error code="404">Not Found</error>
<data xmlns="imaginary"/>
</query>
</iq>
]]></example>
<p>With strict actions disabled, the absence of existing data will not cause the delete action
to fail. Here we show iq:private, and strict actions with no existing data on the server.</p>
<example caption='Client Deletes Private Data but None Found (not strict)'><![CDATA[
SENDER:
<iq type="set" id="1003">
<query xmlns="jabber:iq:private" action="delete" strict="false">
<data xmlns="imaginary"/>
</query>
</iq>
RECIPIENT:
<iq
type="result"
from="hamlet@shakespeare.lit/denmark"
to="hamlet@shakespeare.lit/denmark"
id="1003"/>
]]></example>
</section2>
</section1>
<section1 topic='Defining an Action Protocol'>
<section2 topic='Description'>
<p>In order to define an action protocol that uses the &QUERY; behavior defined in
this document, you must specify the following:</p>
<ul>
<li>The actions (create, read, update, delete) supported in the action protocol.</li>
<li>The matching semantics for determing if data exists/collides.</li>
<li>The default "strict" attribute ('true' or 'false'). This may be defined for each action
supported or for all actions supported.</li>
<li>Whether the "strict" attribute may be set by the user. If the attribute may not be set,
the strict attribute will always hold the default value.</li>
</ul>
</section2>
</section1>
</xep>