For other clients, a "REST level 0", or RPC-like interface is available, using JSON encoded strings for passing parameters and receiving results from services. Each service responds to POST requests to the following URL http[s]://cyclos.url/[network/]web-rpc/<short-service-name>, where the short-service-name is the service with the first letter as lowercase. So, for example, https://my.cyclos.instance.com/network/web-rpc/accountService is a valid URL, being mapped to AccountService.
For authentication, the username and password should be passed as a HTTP header using the standard basic authentication – a header like: "Authentication: Basic <Base64-encoded form of username:password>". Actually, username or other principal type (user identification method) will be chosen according to the configuration. If the configuration allows more than one principal type, it is possible to specify a value in the "Principal-Type" header, which must match the principal type internal name. Alternatively, it is possible to login the user via LoginService and pass the obtained session token in the "Session-Token" header. A third access option is to use an access client token. In this case, the header "Authorization: Bearer <access client token>" is used to specify the access client token.
The request body must be a JSON object with the ‘operation’ and ‘params’ properties, where operation is the method name, and params is either an array with parameters, or optionally the parameter if the method has a single parameter (without the array) or even omitted if the method have no parameters. For objects, the parameters are expected to be the same as the Java counterparts (see the JavaDocs for a reference on the available properties for each object).
As result, if the request was successful (http status code is 200), an object with a single property called result will be returned. The object has the same structure as the object returned by the service method, or is a string, boolean or number for simple types. Requests which resulted in error (status code distinct than 200) will have the following structure:
errorCode: A string generated from the exception java class name. The unqualified class name has the Exception suffix removed, and is transformed to all uppercase, separated by underlines. So, for example, for org.cyclos.model.ValidationException, the error code is VALIDATION; for org.cyclos.model.banking.InsufficientBalanceException, the error code is INSUFFICIENT_BALANCE, and so on.
Any other properties (public getters) the thrown exception has will also be mapped as a property here, for example, org.cyclos.model.ValidationException holds a property called validation which contains an object representing a org.cyclos.utils.ValidationResult.
Apart from that, all objects, when converted to JSON, will have a property called class, which represents the fully-qualified Java class name of the source object. Most clients can just ignore the result. However, when sending requests to classes that expect a polymorphic object, the server needs to know which subclass the passed object represents. In those cases, passing the class property, with the fully qualified Java class name is required. An example is the AdService. When saving an advertisement, it could either be a simple advertisement (AdvertisementDTO) or a webshop advertisement (AdWebShopDTO). In this case, a class property with the fully qualified class name is required. Note, however, that in most cases, the class information is not needed.
Assuming that <root url> points to correct URL, and that the authentication header is correctly passed, the following request can be performed to search for users: The same example call previously shown in Java can be obtained by, posting the following JSON to https://my.cyclos.instance.com/network/web-rpc/userService (assuming the correct request headers / authentication):
{
"operation": "search",
"params": {
"keywords": "consumer",
"pageSize": 5
}
}
The resulting JSON will be something like:
{
"result": {
"class": "org.cyclos.utils.PageImpl",
"currentPage": "0",
"pageSize": "20",
"totalCount": "2",
"pageItems": [
{
"class": "org.cyclos.model.users.users.UserDetailedVO",
"id": "-2717327251475675143",
"name": "Consumer 1",
"username": "c1"
},
{
"class": "org.cyclos.model.users.users.UserDetailedVO",
"id": "-2717467988964030471",
"name": "Consumer 3",
"username": "c3"
}
]
}
}