Project

General

Profile

API Principles » History » Version 7

jerome bonnet, 05/12/2015 04:43 PM

1 6 jerome bonnet
h1. Request and response protocol
2 1 Eric Vieillevigne
3 6 jerome bonnet
h2. API Server principle
4
5 1 Eric Vieillevigne
The API Server is based on the RPC principle. Commands are sent to the server which process them and return responses.
6
7 6 jerome bonnet
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 1 Eric Vieillevigne
However some principles of the REST-FULL APIs are kept:
9
# HTTP protocol.
10 6 jerome bonnet
# No server-side state.
11
# Authentication is not based on a session paradigm. See [[Authentication]].
12 1 Eric Vieillevigne
# 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 6 jerome bonnet
# Full-fledged GUID (every object has a metaId which enables create/update/delete/sync generic operations all all types of objects).
14 1 Eric Vieillevigne
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 6 jerome bonnet
For instance you can have ctcget , ctccreate, ctcupdate, eventget, eventcreate, eventupdate where contact and event are two groups of APIs.
17
This is purely organizational and there are no semantics hidden behind the genre.
18 1 Eric Vieillevigne
19 6 jerome bonnet
Each API has a given set of parameters and output a result:
20 1 Eric Vieillevigne
* 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 6 jerome bonnet
h2. API HTTP Syntax
28 3 Eric Vieillevigne
29 6 jerome bonnet
In order to make call to the Server API, the API caller must be authenticated. See [[Authentication]].
30 1 Eric Vieillevigne
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
> 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 6 jerome bonnet
> 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:
35
36
<pre>
37 1 Eric Vieillevigne
Request header:
38
	Accept-Encoding	gzip
39
	
40
Response header:
41
	Content-Encoding	gzip
42
</pre>
43
44
45 6 jerome bonnet
h3. JSON RPC Syntax
46 5 Eric Vieillevigne
47 1 Eric Vieillevigne
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).
48
49
The JSON RPC Syntax is accessible through the ENDPOINT URL: http(s)://<SERVER_ADDR>/api .
50
51
The particularity of the JSON RPC Syntax is that it enables several API calls to be embedded into one HTTP request.
52
53 6 jerome bonnet
h3. JSON RPC QueryString Format
54 1 Eric Vieillevigne
55
Several API calls can be encoded in one request. The encoding goes like that:
56
# Each API calls is encoded by a set of parameter in the queryString.
57 6 jerome bonnet
# To differentiate one API call from another, the parameter is prefixed by a prefix specific to each API call.
58 1 Eric Vieillevigne
# 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.
59 6 jerome bonnet
# The name of the API is defined by the queryString parameter 'call'
60 1 Eric Vieillevigne
> If no parameter aXXcall is found, the <xx> call is not considered. (xx being the command number)
61
> There may be "holes" in <xx>, but <xx> must be a positive integer. API calls are sorted according the <xx> in ascending order.
62
63
For instance, we want to call the api ctccreate and ctcdelete to create one contact and delete another:
64
> a01call=ctcreate&a01firstName=newContact&a02call=ctcdelete&a02contactIds=4444
65
66
Encoding types goes like that:
67
* Simple types:
68
> Simple types are : String, Boolean, Date, Integer, Long, Enum, etc...
69
> > Boolean are encoded using "true" or "false"
70
71 6 jerome bonnet
> > 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: <pre>api?a01call=ctcupdate2&a01contactId=contact%2F42_1741&a01firstName=eeee&a01birthDate=$empty</pre>
72 1 Eric Vieillevigne
> > Enum are encoded in strings, possible values are constrained. Special values "SOMETHING_ELSE" is used to manage backward compatibility. See [[backward-compatibility]]
73
74
* Complex types:
75
> 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>
76
77
* Arrays
78
> Arrays can be encoded in two way:
79
>> 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>
80
>> encoded by using the . and the index within the array. For instance : <pre>a02call=ctcdelete&a02contactIds.0=4444&a02contactIds.1=5555</pre>
81 6 jerome bonnet
>> The latest method is useful 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>
82 1 Eric Vieillevigne
>> Encoding empty array is possible using the special keyword $empty. Example:
83
<pre>api?a01call=ctcupdate2&a01contactId=contact%2F42_1741&a01firstName=eeee&a01devices=$empty</pre>
84
>> 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.
85
86
* HTTP Headers
87
88
> 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.
89
90
* Media management
91
92
> API parameters can be Files, Medias, byte arrays, blobs, whatever you name them. Their management is specified here: [[MediaManagement]]
93
94 6 jerome bonnet
h3. JSON RPC Output
95 1 Eric Vieillevigne
96
The API will respond in JSON format. The JSON structure is the following:
97
98
# 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.
99
# Second level is a structure containing the name of the api called under 'cn' and the corresponding result, which may be:
100
> # The 'r' key indicate a success (the response). 
101
> # The 'ex' key indicate an error
102
> # The 'un' key indicate an unattended error
103
# 'r': If the result of an API is a simple type (string, integer, boolean, ...), the 'r' element will contains "r":"<value>". 
104
If the result is a complex type, the 'r' element will contains "r": { ... }
105
# 'ex' and 'un': both elements share the same syntax, but indicate either an error or an unattented error. The syntax is:
106
<pre>
107
    "un":{
108
      "un":{
109
        "message":"firstName or lastName must be set",
110
        "FiZClassId":"500"
111
      }
112
    }
113
</pre>
114
115
> FizClassId represents the error code and must be used for any error management by the client. The message is indicative only.
116
117
For complex return type, a corresponding JSON structure is generated.
118
119
> All JSON properties are encoded as String. Integer and boolean are encoded as "123" or "true"
120
121
*Example:*
122
123
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:
124
<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>
125
126
The corresponding result is : 
127
128
<pre>
129
{
130
  "a01":{
131
    "r":{
132
      "r":{
133
        "contactId":"42_1200",
134
        "accountId":"23",
135
        "pictureURIs":[],
136
        "firstName":"coincoin",
137
        "displayName":"coincoin",
138
        "devices":[
139
          {
140
            "deviceType":"PHONE",
141
            "value":"123",
142
            "deviceId":"42_1200_1180"
143
          }
144
        ],
145
        "addresses":[],
146
        "editable":"true"
147
      }
148
    },
149
    "cn":"ctccreate2"
150
  },
151
  "a02":{
152
    "r":{
153
      "r":{
154
        "contactId":"42_1201",
155
        "accountId":"23",
156
        "pictureURIs":[],
157
        "firstName":"coincoin2",
158
        "displayName":"coincoin2",
159
        "devices":[
160
          {
161
            "deviceType":"PHONE",
162
            "value":"123",
163
            "deviceId":"42_1201_1181"
164
          }
165
        ],
166
        "addresses":[],
167
        "editable":"true"
168
      }
169
    },
170
    "cn":"ctccreate2"
171
  },
172
  "a03":{
173
    "cn":"ctccreate",
174
    "un":{
175
      "un":{
176
        "message":"firstName or lastName must be set",
177
        "FiZClassId":"500"
178
      }
179
    }
180
  }
181
}
182
183
</pre>
184
185 6 jerome bonnet
h3. JSON RPC Transaction Management
186 1 Eric Vieillevigne
187
Usually, transaction boundaries and transaction management is handled by the server and totally transparent to the client.
188
189
Optionally, the transaction management can be tuned by the caller:
190
191
> 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.
192
193
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.
194
195
> Example:
196
> <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>
197
> This creates 3 contacts transactionally, but the last call is invalid (no firstname), therefore the 3 api calls are rejected.
198
>
199
> When a transaction is rejected, an attribute "transaction":"aborted" is added in the JSON output:
200
>
201
> <pre>{
202
  "a01":{
203
    "r":{
204
      "r":{
205
        "contactId":"42_1200",
206
        "accountId":"23",
207
        "pictureURIs":[],
208
        "firstName":"coincoin",
209
        "displayName":"coincoin",
210
        "devices":[
211
          {
212
            "deviceType":"PHONE",
213
            "value":"123",
214
            "deviceId":"42_1200_1180"
215
          }
216
        ],
217
        "addresses":[],
218
        "editable":"true"
219
      }
220
    },
221
    "cn":"ctccreate2"
222
  },
223
  "a02":{
224
		....
225
  },
226
  "a03":{
227
    "cn":"ctccreate",
228
    "un":{
229
      "un":{
230
        "message":"firstName or lastName must be set",
231
        "FiZClassId":"500"
232
      }
233
    }
234
  },
235
  "transaction":"aborted"
236
}</pre>
237
238
Note the *"transaction":"aborted"* at the end, indicating that both 3 apis have been actually rollbacked.
239
240 6 jerome bonnet
h3. JSONP RPC Syntax (DEPRECATED)
241 1 Eric Vieillevigne
242 6 jerome bonnet
<pre>
243
JSONP is DEPRECATED in favor of CORS (Cross-Origin Resource Sharing) which is now enabled on all target browser.
244 7 jerome bonnet
See http://www.w3.org/TR/cors/
245 6 jerome bonnet
Authorized domains are configurable on the platform.
246
</pre>
247
248 1 Eric Vieillevigne
The JSONP RPC syntax is a derived syntax from JSON RPC to be used in a Javascript WEB Application context.
249
250
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.
251
See: http://en.wikipedia.org/wiki/JSONP
252
253
The JSONP RPC Syntax is accessible through the ENDPOINT URL: http(s)://<SERVER_ADDR>/api/* .
254
255
The request syntax of JSONP does not allow to have multiple api calls in one http request. However the syntax is easier:
256
<pre>api/<API_GENRE>/<API_NAME>?<API_PARAMETERS>&jsonp=<JSONP_REF></pre>
257
258
JSONP_REF is the name of the JSONP function that will contain the JSON result.
259
260
Example of a create contact with firstName=coincoin and a phone device:
261
<pre> api/ctc/create2?firstName=coincoin&devices.0.deviceType=PHONE&devices.0.value=060606&jsonp=myjsonpname </pre>
262
263
The result of the JSONP is :
264
265
<pre> <JSONP_REF>( { JSON_RESPONSE } ) </pre>
266
267
Example:
268
<pre>
269
myjsonpname(
270
{
271
  "cn":"ctccreate2",
272
  "feed":{
273
    "contactId":"42_1202",
274
    "accountId":"23",
275
    "pictureURIs":[],
276
    "firstName":"coincoin",
277
    "displayName":"coincoin",
278
    "devices":[
279
      {
280
        "deviceType":"PHONE",
281
        "value":"060606",
282
        "deviceId":"42_1202_1182"
283
      }
284
    ],
285
    "addresses":[],
286
    "editable":"true"
287
  }
288
}
289
)
290
</pre>