Project

General

Profile

RequestResponseProtocol » History » Version 3

jerome bonnet, 06/01/2012 02:55 PM

1 1 jerome bonnet
h1. Request and response protocol
2
3
h2. API Server principle
4
5
The API Server is based on the RPC principle. Commands are sent to the server which process them and return responses.
6
7
The API Server is not based on the REST-FULL principle, because the feature and the coverage of the API is not limited to CRUD behavior, plus other issues not to be discussed here.
8
However some principles of the REST-FULL APIs are kept:
9
# HTTP protocol.
10
# No server-side state (except for authent. v0).
11
# Except for the first authentification protocol (authent. v0), authentification is not based on a session paradigm. See [[Authentification]].
12
# No session. The server is session-less, even if the client must support a JSESSIONID cookie for performance purposes, the JSESSIONID cookie value may be changed at any time by the server or may be forgotten by the client at any time.
13
# Full-fledged GUID (TBD).
14
15
The APIs are defined by a set of possible command grouped by genre. Each API has a name which begins with the group name.
16
For instance you can have ctcget , ctccreate, ctcupdate, eventget, eventcreate, eventupdate where contact and event are two groups of APIs.
17
This is purely organisational and there are no semantics hidden behind the genre.
18
19
Each api has a given set of parameters and output a result:
20
* Parameters: Each parameter has a name, a type (String,Integer,Boolean,Enum,Date,List,etc...). Each parameter may be required or optional.
21
Parameters can also be of complex type such as a structure or a collection (array, map)...
22
* Result: Each result is a well-defined data structure. It may be a simple type (Boolean, String, etc) or a complex structure.
23
* Error: Each api may return an error instead of the result. The error is composed of a type, a code (integer) and eventually extra parameters. 
24
	The error maybe Attended errors or Unattended errors. 
25
	All possible Attended error codes is well-defined for each APIs whereas Unattended error codes are possible for any APIs.
26
27
h2. API HTTP Syntax
28
29
In order to make call to the Server API, the API caller must be authentified. See [[Authentification]].
30
Within the HTTP protocol, HTTP request indicates the name and the parameters of api to call. HTTP Response returned by the server contains the result of the call. Several syntax to encode the requests and the response is proposed.
31
32 2 jerome bonnet
> Encoding: *UTF8*. The encoding of queryString parameters (notably in GET) is decoded by the server in UTF8. Note that this is different from the common usage and RFC that normally requires that GET parameters are encoded/decoded in ISO-8859-1.
33
34
> Compression: *GZIP*. Because the response can be big and the network can be slow, especially on mobile network, the client MUST ask for GZIP compression for JSON. The server must return GZIPPED content in this case. Example: <pre>
35
Request header:
36
	Accept-Encoding	gzip
37
	
38
Response header:
39
	Content-Encoding	gzip
40
</pre>
41
42
43 1 jerome bonnet
h3. JSON RPC Syntax
44
45
The JSON RPC Syntax encode the API request within the HTTP queryString (either in GET or POST) and the result is returned in the HTTP response as a JSON document (mime application/json).
46
47
The JSON RPC Syntax is accessible through the ENDPOINT URL: http(s)://<SERVER_ADDR>/api .
48
49
The particularity of the JSON RPC Syntax is that it enables several API calls to be embedded into one HTTP request.
50
51
h3. JSON RPC QueryString Format
52
53
Several API calls can be encoded in one request. The encoding goes like that:
54
# Each API calls is encoded by a set of parameter in the queryString.
55
# To differenciate one API call from another, the parameter is prefixed by a prefix specific to each api call.
56
# The prefix is always 3 characters, beginning with a letter and then 2 digits. The letter 'a' shall be used by default, other letters being reserved for future usage.
57
# The name of the api is defined by the queryString parameter 'call'
58
> If no parameter aXXcall is found, the <xx> call is not considered. (xx being the command number)
59
> There may be "holes" in <xx>, but <xx> must be a positive integer. API calls are sorted according the <xx> in ascending order.
60
61
For instance, we want to call the api ctccreate and ctcdelete to create one contact and delete another:
62
> a01call=ctcreate&a01firstName=newContact&a02call=ctcdelete&a02contactIds=4444
63
64
Encoding types goes like that:
65
* Simple types:
66
> Simple types are : String, Boolean, Date, Integer, Long, Enum, etc...
67
> > Boolean are encoded using "true" or "false"
68 3 jerome bonnet
69
> > Date are encoded according to ISO 8601 in "Z" format. Special values for setting specific empty date is $empty. It is used for instance to remove birthday from contacts:
70
<pre>api?a01call=ctcupdate2&a01contactId=contact%2F42_1741&a01firstName=eeee&a01birthDate=$empty</pre>
71 1 jerome bonnet
> > Enum are encoded in strings, possible values are constrained. Special values "SOMETHING_ELSE" is used to manage backward compatibility. See [[backward-compatibility]]
72
73
* Complex types:
74
> Complex types are encoded using the . as the property separator. For instance, the device of a contact is a complex type composed of 3 properties : deviceId, deviceType and value. A parameter 'device' of type Device is encoded like that: <pre> device.deviceId=123&device.deviceType=MOBILE&device.value=0633445566 </pre>
75
76
* Arrays
77
> Arrays can be encoded in two way:
78
>> encoded either using the classic "html form" format, repeating the parameter several times. For instance in the api ctcdelete, contactIDs is an array of integer: <pre>a02call=ctcdelete&a02contactIds=4444&a02contactIds=5555</pre>
79
>> encoded by using the . and the index within the array. For instance : <pre>a02call=ctcdelete&a02contactIds.0=4444&a02contactIds.1=5555</pre>
80
>> The lastest method is usefull when encoding an array of complex type. For instance in ctccreate2 the parameter devices is an array of Device : <pre>api?a01call=ctccreate2&a01firstName=coincoin&a01devices.0.deviceType=PHONE&a01devices.0.value=123&a01devices.1.deviceType=EMAIL&a01devices.1.value=toot%40x.com</pre>
81 3 jerome bonnet
>> Encoding empty array is possible using the special keyword $empty. Example:
82
<pre>api?a01call=ctcupdate2&a01contactId=contact%2F42_1741&a01firstName=eeee&a01devices=$empty</pre>
83
>> This enables you to specifically set an empty array onto an object. For instance here it is used to remove all devices from a contact.
84 1 jerome bonnet
85
* HTTP Headers
86
87
> HTTP headers does not transport request parameters per-se. They may be used with their original HTTP semantics. Some API use them as parameters (see wallnotification), but this usage is deprecated.
88
89
* Media management
90
91
> API parameters can be Files, Medias, byte arrays, blobs, whatever you name them. Their management is specified here: [[MediaManagement]]
92
93
h3. JSON RPC Output
94
95
The API will respond in JSON format. The JSON structure is the following:
96
97
# First level in JSON is the list of apis calls performed in the http request. Key is the prefix (ie a01) and value is the result of the api.
98
# Second level is a structure containing the name of the api called under 'cn' and the corresponding result, which may be:
99
> # The 'r' key indicate a success (the response). 
100
> # The 'ex' key indicate an error
101
> # The 'un' key indicate an unattended error
102
# 'r': If the result of an API is a simple type (string, integer, boolean, ...), the 'r' element will contains "r":"<value>". 
103
If the result is a complex type, the 'r' element will contains "r": { ... }
104
# 'ex' and 'un': both elements share the same syntax, but indicate either an error or an unattented error. The syntax is:
105
<pre>
106
    "un":{
107
      "un":{
108
        "message":"firstName or lastName must be set",
109
        "FiZClassId":"500"
110
      }
111
    }
112
</pre>
113
114
> FizClassId represents the error code and must be used for any error management by the client. The message is indicative only.
115
116
For complex return type, a corresponding JSON structure is generated.
117
118
> All JSON properties are encoded as String. Integer and boolean are encoded as "123" or "true"
119
120
*Example:*
121
122
We are calling 3 apis to create 3 contacts in one HTTP call. The 3rd create contact is invalid and therefore will return an error:
123
<pre> api?a01call=ctccreate2&a01firstName=coincoin&a01devices.0.deviceType=PHONE&a01devices.0.value=123&a02call=ctccreate2&a02firstName=coincoin2&a02devices.0.deviceType=PHONE&a02devices.0.value=123&a03call=ctccreate&transactional=true </pre>
124
125
The corresponding result is : 
126
127
<pre>
128
{
129
  "a01":{
130
    "r":{
131
      "r":{
132
        "contactId":"42_1200",
133
        "accountId":"23",
134
        "pictureURIs":[],
135
        "firstName":"coincoin",
136
        "displayName":"coincoin",
137
        "devices":[
138
          {
139
            "deviceType":"PHONE",
140
            "value":"123",
141
            "deviceId":"42_1200_1180"
142
          }
143
        ],
144
        "addresses":[],
145
        "editable":"true"
146
      }
147
    },
148
    "cn":"ctccreate2"
149
  },
150
  "a02":{
151
    "r":{
152
      "r":{
153
        "contactId":"42_1201",
154
        "accountId":"23",
155
        "pictureURIs":[],
156
        "firstName":"coincoin2",
157
        "displayName":"coincoin2",
158
        "devices":[
159
          {
160
            "deviceType":"PHONE",
161
            "value":"123",
162
            "deviceId":"42_1201_1181"
163
          }
164
        ],
165
        "addresses":[],
166
        "editable":"true"
167
      }
168
    },
169
    "cn":"ctccreate2"
170
  },
171
  "a03":{
172
    "cn":"ctccreate",
173
    "un":{
174
      "un":{
175
        "message":"firstName or lastName must be set",
176
        "FiZClassId":"500"
177
      }
178
    }
179
  }
180
}
181
182
</pre>
183
184
h3. JSON RPC Transaction Management
185
186
Usually, transaction boundaries and transaction management is handled by the server and totally transparent to the client.
187
188
Optionally, the transaction management can be tuned by the caller:
189
190
> There is some case where the caller encode several api calls in one http request and may want that all of the api calls participate in only one transaction. For instance, you may want to set-up a sign-up process that perform: log2create (create an account) and acccreatefamily (create your own family). In this case it is interesting to have a single atomic transaction context for those two apis.
191
192
In this case, the parameter "transactional=true" my be used and will use only one atomic transaction to encapsulate all api call of the current http request.
193
194
> Example:
195
> <pre> api?a01call=ctccreate2&a01firstName=coincoin&a01devices.0.deviceType=PHONE&a01devices.0.value=123&a02call=ctccreate2&a02firstName=coincoin2&a02devices.0.deviceType=PHONE&a02devices.0.value=123&a03call=ctccreate&transactional=true </pre>
196
> This creates 3 contacts transactionally, but the last call is invalid (no firstname), therefore the 3 api calls are rejected.
197
>
198
> When a transaction is rejected, an attribute "transaction":"aborted" is added in the JSON output:
199
>
200
> <pre>{
201
  "a01":{
202
    "r":{
203
      "r":{
204
        "contactId":"42_1200",
205
        "accountId":"23",
206
        "pictureURIs":[],
207
        "firstName":"coincoin",
208
        "displayName":"coincoin",
209
        "devices":[
210
          {
211
            "deviceType":"PHONE",
212
            "value":"123",
213
            "deviceId":"42_1200_1180"
214
          }
215
        ],
216
        "addresses":[],
217
        "editable":"true"
218
      }
219
    },
220
    "cn":"ctccreate2"
221
  },
222
  "a02":{
223
		....
224
  },
225
  "a03":{
226
    "cn":"ctccreate",
227
    "un":{
228
      "un":{
229
        "message":"firstName or lastName must be set",
230
        "FiZClassId":"500"
231
      }
232
    }
233
  },
234
  "transaction":"aborted"
235
}</pre>
236
237
Note the *"transaction":"aborted"* at the end, indicating that both 3 apis have been actually rollbacked.
238
239
h3. JSONP RPC Syntax
240
241
The JSONP RPC syntax is a derived syntax from JSON RPC to be used in a Javascript WEB Application context.
242
243
The purpose of this JSONP api is to return a JSON modified format of the API in order to remove the same-origin issue of Javascript applications.
244
See: http://en.wikipedia.org/wiki/JSONP
245
246
The JSONP RPC Syntax is accessible through the ENDPOINT URL: http(s)://<SERVER_ADDR>/api/* .
247
248
The request syntax of JSONP does not allow to have multiple api calls in one http request. However the syntax is easier:
249
<pre>api/<API_GENRE>/<API_NAME>?<API_PARAMETERS>&jsonp=<JSONP_REF></pre>
250
251
JSONP_REF is the name of the JSONP function that will contain the JSON result.
252
253
Example of a create contact with firstName=coincoin and a phone device:
254
<pre> api/ctc/create2?firstName=coincoin&devices.0.deviceType=PHONE&devices.0.value=060606&jsonp=myjsonpname </pre>
255
256
The result of the JSONP is :
257
258
<pre> <JSONP_REF>( { JSON_RESPONSE } ) </pre>
259
260
Example:
261
<pre>
262
myjsonpname(
263
{
264
  "cn":"ctccreate2",
265
  "feed":{
266
    "contactId":"42_1202",
267
    "accountId":"23",
268
    "pictureURIs":[],
269
    "firstName":"coincoin",
270
    "displayName":"coincoin",
271
    "devices":[
272
      {
273
        "deviceType":"PHONE",
274
        "value":"060606",
275
        "deviceId":"42_1202_1182"
276
      }
277
    ],
278
    "addresses":[],
279
    "editable":"true"
280
  }
281
}
282
)
283
</pre>
284
285
h2. API definition and htmlform
286
287
The server is self-generating a test page called htmlform (url is <SERVER_URL>/htmlform) and containing all APIs definition.
288
289
Examples:
290
<pre>
291
Method : ctccreate2
292
create a contact
293
	a01firstName 		
294
	a01lastName 		
295
	a01function 		
296
	a01gender 		
297
	a01birthDate 		
298
	a01pictures 	+ - 	
299
	a01devices 	+ - 	
300
		a01devices.0.deviceId 		
301
		a01devices.0.deviceType 		
302
		a01devices.0.value 		
303
	a01adresses 	+ - 	
304
	a01adresseTypes 	+ - 	
305
306
Return : IContact
307
308
Error codes:
309
FizContactAlreadyExistsException	200
310
FizMediaQuotaExceededException	601
311
</pre>
312
313
Below the description of the API, the list of parameters is defined, and then the return type and the possible error codes.