This documentation is obsolete. Check out the API v3 documentation for more up to date information.
This page is dedicated to suggestions for improving the REST interface to the API. This work is related to the overall API improvements related to the API function naming scheme .
Please make additions or suggestions.
Goals
- REST interface that wraps all API functions safely and effectively
- A sensible and effective security system
- Leverage API naming conventions to expose all API functions consistently
- Develop unit tests that can work against the API
URL Scheme
Currently the URL's have the following form:
The current form of this proposal would switch to:
Parameter details:
- q (required)
- this is the function name to be called. 2 parts for login and ping, 3 parts for all main API calls. Example:
- this is the function name to be called. 2 parts for login and ping, 3 parts for all main API calls. Example:
- key (required)
- this is the server's API key, set in a configuration file, acts as master switch to the API
- this is the server's API key, set in a configuration file, acts as master switch to the API
- api_key (required for all except login and ping)
- this is the user's API key, that identifies the user calling the API. This key is assigned when the login function is first called. There is currently no way to reset this key without editing the database.
- this is the user's API key, that identifies the user calling the API. This key is assigned when the login function is first called. There is currently no way to reset this key without editing the database.
- Param1 - ParamN: (vary depending on function being called)
- Additional parameters are combined into a hash, used as parameters for the main API functions.
- Additional parameters are combined into a hash, used as parameters for the main API functions.
Proposed replacement parameter scheme:
- function (required)
- This is the object/function to be called. It would be in 2 parts for all functions (except login, ping, and a new one called 'reset'), object/function.
- Advantages: Makes the purpose of the parameter clearer, removing unneeded name spacing provided by the old 'civicrm' requirement. The civicrm element was ignored in the interface handling code of the older version to allow the security of forcing the opening onto the function (to help avoid arbiratry code execution through the interface). The prepending of the function name does not require inclusion in the the parameter.
- This is the object/function to be called. It would be in 2 parts for all functions (except login, ping, and a new one called 'reset'), object/function.
- skey (required)
- This would replace the old 'key' parameter.
- Advantages: makes for clearer purpose of the parameter.
- Note: While it may appear that this key is not strickly required given the presence of the user's key, until there is a good way to better control which users can use the interface, this key provides a way to lock out users that have not been given access to the interface by an administrator. Also, changing this key locks out any users who many already have access but need to be kicked out after they have gained access. It would be good to improve other aspects of the system so that this key is redudant.
- This would replace the old 'key' parameter.
- ukey: (required for all except login and reset)
- This would replace the old 'api_key' parameter.
- Advantages: Clarifies the difference from the skey, and will hopefully help people remember which is which.
- This would replace the old 'api_key' parameter.
- v (optional)
- If there were a version flag of some kind on the main API, it might be possible to preserve consistent responses across changes to BAO but also allow the interface to smoothly move forward.
Non-API Functions:
Currently there are two functions in the REST interface that are not in the main API: login, ping. Login is used to create user API keys, and used to be used to create session keys (which still works but frequently causes problems during development). Ping just replies that the API is active. Currently there is no way to prevent any user with a valid password from creating a key, and no way to reset/remove a key after it has been created. The first problem still needs a solution (everything I can think of is fairly complicated)! The second two could be solved by adding a third function: reset. When called with a username/password it would generate a new API key, when called with a valid key, it could remove the current key.
Login:
The current login function returns 3 keys, 2 of which are not needed for anything. The PHPSESSION key (which has been problematic) and the api_key, and another user key. Only the api_key field is needed to make the interface work. The function also returns the server time as 'rest_time' which causes no harm, but does get used by other portions of the interface.
Reset:
The reset function would provide a scheme to reset a user's api_key, or disable a user's API access. It would take either a username/password pair, or the user's API key. While this could be accomplished through the login function, it seems a little odd to have a function named loging handle these opperations. This function would only answer to the GET HTTP verb (see below).
HTTP verbs:
Currently the REST interface responds to both POST and GET calls interchangeably for all API functions. PHP makes it hard to handle ADD and DELETE actions, particularly given that is common for apache servers to have those actions disabled as a general security precaution. However, it is poor design to have the system make changes to the database on GET calls. Therefore, I suggest for the 2.x branch we switch to doing only 'get' actions on GET calls, and all other functions (create/update/delete) require using 'POST'. When CiviCRM progresses to 3.x it would be wise to re-open this question.
When more than one API function call is needed:
There has been a suggestion that there are times when it would useful to call more than 1 API function in rapid succession, and atomicity of the pair of calls would be needed. These scheme does not currently address that problem.
Custom API calls:
There has been a suggestion that the main API get the ability to add custom functions. If these functions were placed in a consistent place, and obeyed the naming scheme of the main API, it seems likely that it would be easy to enable either through the 'v' parameter above, or adding name spacing onto the 'function' parameter.

1 Comment
Hide/Show CommentsMay 11, 2009
JoeMurray
Lots of work has gone into this and I'm a bit out of my depth (or maybe the above just summarizes some things I still don't completely understand). Would still like to contribute a bit which might be useful:
On session variables, is this related to the issues that arise when multiple broswer tabs are opened and trying to work on the same data? Will the proposed solution be able to play nice with Drupal sessions with both the standard session variable and specially named ones, such as those used for various single sign-on modules for drupal?
Regarding skey - what is the server here? Would domain key be a better term? Some installations may want to support web server clusters and / or database server clusters, and this term seems slightly inaccurate.