aboutsummaryrefslogtreecommitdiff
path: root/xep-0099.xml
blob: b9efee783c174e7d6435877a1a38124a1b98fae2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
<?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</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 it's 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>