Project

General

Profile

API Principles » History » Version 3

Eric Vieillevigne, 05/12/2015 07:48 AM

1 1 Eric Vieillevigne
h1. API Server principle
2
3
The API Server is based on the RPC principle. Commands are sent to the server which process them and return responses.
4
5
The API Server is not based on the REST-FULL principle as the feature and the coverage of the API is not limited to CRUD behavior
6
.
7
However some principles of the REST-FULL APIs are kept:
8
# HTTP protocol.
9
# No server-side state (except for authent. v0).
10
# Except for the first authentification protocol (authent. v0), authentification is not based on a session paradigm. See [[Authentification]].
11
# 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.
12
# Full-fledged GUID.
13
14
The APIs are defined by a set of possible command grouped by genre. Each API has a name which begins with the group name.
15
For example, you can chain _ctcget_ , _ctccreate_, _ctcupdate_, _eventget_, _eventcreate_, _eventupdate_ where contact and event are two groups of APIs.
16
This is purely organisational and there are no semantics hidden behind the genre.
17
18
Each API has a given set of parameters and output as a result:
19
* Parameters: Each parameter has a name, a type (String,Integer,Boolean,Enum,Date,List,etc...). Each parameter may be required or optional.
20
Parameters can also be of complex type such as a structure or a collection (array, map)...
21
* Result: Each result is a well-defined data structure. It may be a simple type (Boolean, String, etc) or a complex structure.
22
* 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. 
23
	The error maybe Attended errors or Unattended errors. 
24
	All possible Attended error codes is well-defined for each APIs whereas Unattended error codes are possible for any APIs.
25
26 3 Eric Vieillevigne
27 1 Eric Vieillevigne
h1. API HTTP Syntax
28 2 Eric Vieillevigne
29 1 Eric Vieillevigne
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
> 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
h2. JSON RPC Syntax
44
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).
45
46
The JSON RPC Syntax is accessible through the ENDPOINT URL: http(s)://<SERVER_ADDR>/api .
47
48
The particularity of the JSON RPC Syntax is that it enables several API calls to be embedded into one HTTP request.
49
50
h2. JSON RPC QueryString Format
51
52
Several API calls can be encoded in one request. The encoding goes like that:
53
# Each API calls is encoded by a set of parameter in the queryString.
54
# To differenciate one API call from another, the parameter is prefixed by a prefix specific to each api call.
55
# 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.
56
# The name of the api is defined by the queryString parameter 'call'
57
> If no parameter aXXcall is found, the <xx> call is not considered. (xx being the command number)
58
> There may be "holes" in <xx>, but <xx> must be a positive integer. API calls are sorted according the <xx> in ascending order.
59
60
For instance, we want to call the api ctccreate and ctcdelete to create one contact and delete another:
61
> a01call=ctcreate&a01firstName=newContact&a02call=ctcdelete&a02contactIds=4444
62
63
Encoding types goes like that:
64
* Simple types:
65
> Simple types are : String, Boolean, Date, Integer, Long, Enum, etc...
66
> > Boolean are encoded using "true" or "false"
67
68
> > 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:
69
<pre>api?a01call=ctcupdate2&a01contactId=contact%2F42_1741&a01firstName=eeee&a01birthDate=$empty</pre>
70
> > Enum are encoded in strings, possible values are constrained. Special values "SOMETHING_ELSE" is used to manage backward compatibility. See [[backward-compatibility]]
71
72
* Complex types:
73
> 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>
74
75
* Arrays
76
> Arrays can be encoded in two way:
77
>> 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>
78
>> encoded by using the . and the index within the array. For instance : <pre>a02call=ctcdelete&a02contactIds.0=4444&a02contactIds.1=5555</pre>
79
>> 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>
80
>> Encoding empty array is possible using the special keyword $empty. Example:
81
<pre>api?a01call=ctcupdate2&a01contactId=contact%2F42_1741&a01firstName=eeee&a01devices=$empty</pre>
82
>> 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.
83
84
* HTTP Headers
85
86
> 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.
87
88
* Media management
89
90
> API parameters can be Files, Medias, byte arrays, blobs, whatever you name them. Their management is specified here: [[MediaManagement]]
91
92
h2. JSON RPC Output
93
94
The API will respond in JSON format. The JSON structure is the following:
95
96
# 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.
97
# Second level is a structure containing the name of the api called under 'cn' and the corresponding result, which may be:
98
> # The 'r' key indicate a success (the response). 
99
> # The 'ex' key indicate an error
100
> # The 'un' key indicate an unattended error
101
# 'r': If the result of an API is a simple type (string, integer, boolean, ...), the 'r' element will contains "r":"<value>". 
102
If the result is a complex type, the 'r' element will contains "r": { ... }
103
# 'ex' and 'un': both elements share the same syntax, but indicate either an error or an unattented error. The syntax is:
104
<pre>
105
    "un":{
106
      "un":{
107
        "message":"firstName or lastName must be set",
108
        "FiZClassId":"500"
109
      }
110
    }
111
</pre>
112
113
> FizClassId represents the error code and must be used for any error management by the client. The message is indicative only.
114
115
For complex return type, a corresponding JSON structure is generated.
116
117
> All JSON properties are encoded as String. Integer and boolean are encoded as "123" or "true"
118
119
*Example:*
120
121
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:
122
<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>
123
124
The corresponding result is : 
125
126
<pre>
127
{
128
  "a01":{
129
    "r":{
130
      "r":{
131
        "contactId":"42_1200",
132
        "accountId":"23",
133
        "pictureURIs":[],
134
        "firstName":"coincoin",
135
        "displayName":"coincoin",
136
        "devices":[
137
          {
138
            "deviceType":"PHONE",
139
            "value":"123",
140
            "deviceId":"42_1200_1180"
141
          }
142
        ],
143
        "addresses":[],
144
        "editable":"true"
145
      }
146
    },
147
    "cn":"ctccreate2"
148
  },
149
  "a02":{
150
    "r":{
151
      "r":{
152
        "contactId":"42_1201",
153
        "accountId":"23",
154
        "pictureURIs":[],
155
        "firstName":"coincoin2",
156
        "displayName":"coincoin2",
157
        "devices":[
158
          {
159
            "deviceType":"PHONE",
160
            "value":"123",
161
            "deviceId":"42_1201_1181"
162
          }
163
        ],
164
        "addresses":[],
165
        "editable":"true"
166
      }
167
    },
168
    "cn":"ctccreate2"
169
  },
170
  "a03":{
171
    "cn":"ctccreate",
172
    "un":{
173
      "un":{
174
        "message":"firstName or lastName must be set",
175
        "FiZClassId":"500"
176
      }
177
    }
178
  }
179
}
180
181
</pre>
182
183
h2. JSON RPC Transaction Management
184
185
Usually, transaction boundaries and transaction management is handled by the server and totally transparent to the client.
186
187
Optionally, the transaction management can be tuned by the caller:
188
189
> 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.
190
191
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.
192
193
> Example:
194
> <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>
195
> This creates 3 contacts transactionally, but the last call is invalid (no firstname), therefore the 3 api calls are rejected.
196
>
197
> When a transaction is rejected, an attribute "transaction":"aborted" is added in the JSON output:
198
>
199
> <pre>{
200
  "a01":{
201
    "r":{
202
      "r":{
203
        "contactId":"42_1200",
204
        "accountId":"23",
205
        "pictureURIs":[],
206
        "firstName":"coincoin",
207
        "displayName":"coincoin",
208
        "devices":[
209
          {
210
            "deviceType":"PHONE",
211
            "value":"123",
212
            "deviceId":"42_1200_1180"
213
          }
214
        ],
215
        "addresses":[],
216
        "editable":"true"
217
      }
218
    },
219
    "cn":"ctccreate2"
220
  },
221
  "a02":{
222
		....
223
  },
224
  "a03":{
225
    "cn":"ctccreate",
226
    "un":{
227
      "un":{
228
        "message":"firstName or lastName must be set",
229
        "FiZClassId":"500"
230
      }
231
    }
232
  },
233
  "transaction":"aborted"
234
}</pre>
235
236
Note the *"transaction":"aborted"* at the end, indicating that both 3 apis have been actually rollbacked.
237
238
h3. JSONP RPC Syntax
239
240
The JSONP RPC syntax is a derived syntax from JSON RPC to be used in a Javascript WEB Application context.
241
242
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.
243
See: http://en.wikipedia.org/wiki/JSONP
244
245
The JSONP RPC Syntax is accessible through the ENDPOINT URL: http(s)://<SERVER_ADDR>/api/* .
246
247
The request syntax of JSONP does not allow to have multiple api calls in one http request. However the syntax is easier:
248
<pre>api/<API_GENRE>/<API_NAME>?<API_PARAMETERS>&jsonp=<JSONP_REF></pre>
249
250
JSONP_REF is the name of the JSONP function that will contain the JSON result.
251
252
Example of a create contact with firstName=coincoin and a phone device:
253
<pre> api/ctc/create2?firstName=coincoin&devices.0.deviceType=PHONE&devices.0.value=060606&jsonp=myjsonpname </pre>
254
255
The result of the JSONP is :
256
257
<pre> <JSONP_REF>( { JSON_RESPONSE } ) </pre>
258
259
Example:
260
<pre>
261
myjsonpname(
262
{
263
  "cn":"ctccreate2",
264
  "feed":{
265
    "contactId":"42_1202",
266
    "accountId":"23",
267
    "pictureURIs":[],
268
    "firstName":"coincoin",
269
    "displayName":"coincoin",
270
    "devices":[
271
      {
272
        "deviceType":"PHONE",
273
        "value":"060606",
274
        "deviceId":"42_1202_1182"
275
      }
276
    ],
277
    "addresses":[],
278
    "editable":"true"
279
  }
280
}
281
)
282
</pre>
283
284
h2. API definition and htmlform
285
286
The server is self-generating a test page called htmlform (url is <SERVER_URL>/htmlform) and containing all APIs definition.
287
288
Examples:
289
<pre>
290
Method : ctccreate2
291
create a contact
292
	a01firstName 		
293
	a01lastName 		
294
	a01function 		
295
	a01gender 		
296
	a01birthDate 		
297
	a01pictures 	+ - 	
298
	a01devices 	+ - 	
299
		a01devices.0.deviceId 		
300
		a01devices.0.deviceType 		
301
		a01devices.0.value 		
302
	a01adresses 	+ - 	
303
	a01adresseTypes 	+ - 	
304
305
Return : IContact
306
307
Error codes:
308
FizContactAlreadyExistsException	200
309
FizMediaQuotaExceededException	601
310
</pre>
311
312
Below the description of the API, the list of parameters is defined, and then the return type and the possible error codes.