miroir de https://github.com/moparisthebest/xeps
402 lignes
14 KiB
XML
402 lignes
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>
|