Extending REST APIs
Extending REST APIs:CSServices¶
The CSServices container is dedicated to Content Scripts that should be made available as REST services.
The name of scripts placed in this container can be used to invoke the script directly through two dedicated HTTP endpoint (amcsapi, amcsapi/v1)
The amcsapi can be used to consume the REST service from within the Content Server GUI (it will in fact use the standard Content Server authentication mechanism to authenticate the user).
On the other hand the amcsapi/v1 can be used to consume the REST service using the Content Server REST Apis authentication token.
When invoked, unless otherwise specified (for example, in the script’s “Run As” configuration), each script is executed as the currently logged in user.
Basic REST service¶
As a very simple example, the script getuserbyname can be invoked by using an URL built as follows:
http://localhost/otcs/cs.exe/amcsapi/getuserbyname
http://localhost/otcs/cs.exe/amcsapi/v1/getuserbyname
Additional parameters can be passed to the service, and will be available in the Content Script (via the params object). For example, invoking the previous script as:
http://localhost/otcs/cs.exe/amcsapi/getuserbyname?term=admin
the REST service framework will run the backing getuserbyname script adding the value of the GET parameter term in the params container variable. In the script, the value will be accessible by simply using the expression:
params.term
Behaviour based REST services¶
Since version 1.7.0, Content Script supports a “behaviour” based approach for the creation of REST services. This allows for an easier set-up of new services, enhance maintainability and better compliance with REST service commonly used conventions and de-facto standards.
A skeleton for a behaviour-based REST service is shown below.
A REST service can specify multiple operations, identified with behaviours. Each behaviour is implemented as a closure. By convention, the home behaviour is bound to the root of the API.
Service example¶
log.debug("Content Script REST Service {} - START", self?.name) section = { String elemID=null, String method=null, String param=null -> try { if(elemID){ switch(params.method){ case "GET": //Read json( [ operation:"section", elemID:elemID, method: method, param: param ] ) return; default : response.error("Unsupported operation",500) return } }else{ json( [ operation:"section", elemID:elemID, method: method, param: param ] ) return } } catch(e){ log.error("An error has occurred while managing the request", e) json([error:"Unable to complete your request $e?.message"]) } } //Default service method home = { String elemID -> try { //Single element if(elemID){ switch(params.method){ //request verb // CRUD operations case "POST": //Create //Your code here... break; case "GET": //Read json(["elemID":elemID]) return; case "PUT": //Update //Your code here... break; case "DELETE": //Delete //Your code here... break; } }else{ switch(params.method){ //request verb // CRUD operations case "POST": //Create //Your code here... break; case "GET": //Read //Your code here... break; case "PUT": //Update //Your code here... break; case "DELETE": //Delete //Your code here... break; } } // Default return json([ok:true]) } catch(e){ log.error("An error has occurred while managing the request", e) json([error:"Unable to complete your request $e?.message"]) } } if(!BehaviourHelper.hasBehaviour(this, "start")) { BehaviourHelper.addBeahaviours(this, AMRestController.getBehaviours()) } return start() log.debug("Content Script REST Service {} - END", self?.name)
Sample invocation path | Operation | Parameters passed to the closure |
---|---|---|
/training | home | elemID = null |
/training/2000 | home | elemID = “2000” |
/training/2000/section | section | elemID = “2000” method = null param =null |
/training/2000/section/100 | section | elemID = “2000” method = “100” param =null |
/training/2000/section/100/list | section | elemID = “2000” method = “100” param =“list” |
/training/section/2000 | section | elemID = “2000” method = null param =null |
/training/section/2000/100 | section | elemID = “2000” method = “100” param =null |
/training/section/2000/100/list | section | elemID = “2000” method = “100” param =“list” |