mirror of https://github.com/moparisthebest/xeps
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
14 KiB
401 lines
14 KiB
<?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>
|
|
|