CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Versioning
Pages: [1]

Author Topic: Versioning  (Read 911 times)

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Versioning
November 23, 2010, 11:00:05 am
Hi,

On a Skype call those of the API team who were present (the same people who drag ever conversation into a series of poor jokes about warm beer) agreed that the best way to introduce changes that would be difficult to integrate into existing code would be by shipping more than one version of the api. This will see an API folder with subfolders v2 (existing), v3 and v4.

One the top level there will be a function e.g.

Code: [Select]
function civicrm_contact_get($params){

if (empty($params['version']){
 $params['version'] = 2;
}

require_once 'civicrm/api/v' . $params['version'] . '/Contact.php';
civicrm_contact_get($params);
}


The advantage of this is:
1) This allows us to introduce changes to the API that aren't easily backwards compatible by introducting a new version of the API. For example v2 contribute_get returns an error message if more than one contact is returned which is not compatible with our v3 standard but some code using this API will rely on it
2) Mean that no version 2 code is broken by the introduction of the v3 (&v4) APIs
3) Mean that when people want to change version they only have to change one parameter which means
4) We can be pretty rigid about only supporting the latest version of a given API

The downside is that more code is shipped but we felt better that than break peoples code or try to deal with deprecation by writing complex code.

v3 standard is primarily
1) use correct verbs (create, get, delete)
2) array in / array out
3) $params['version'] is compulsory
4) deprecated functions can GO
5) Test & documentation coverage is at least as good as it is currently

V4 standard is still being determined and v4 standard will be applied to v3 so far as it can be without cause difficulty for existing code

We didn't want to set the bar too high for v3 because there are a bunch of fairly superficial changes (primarily 1 & 2) that can be implemented fairly quickly once we stop having to worry about deprecation and will make it a lot easier to move forward with our more sophisticated wishlist.

SO, having explained ALL that my question is... Can someone suggest a more elegant approach to the function above?
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Versioning
November 23, 2010, 11:24:31 am
NB does it become more like the function called is


function civicm_api($function, $class, $params){
if (empty($params['version']){
 $params['version'] = 2;
}

require_once 'civicrm/api/v' . $params['version'] . '/' . $class .'.php';
$function($params);
}


so people call eg

$result = civicrm_api('civicrm_contact_get', 'Contact', $params){


}
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

demeritcowboy

  • Ask me questions
  • ****
  • Posts: 570
  • Karma: 42
  • CiviCRM version: Always the latest!
  • CMS version: Drupal 6 mostly, still evaluating 7.
  • MySQL version: Mix of 5.0 / 5.1 / 5.5
  • PHP version: 5.3, usually on Windows
Re: Versioning
November 23, 2010, 12:51:37 pm
For the beer there is probably a third-party librewery that could be used to avoid re-inventing the barrel.

Just to clarify backwards compatibility when you say "deprecated functions can GO" you are still intending to distribute the old v2 folder with every new release so we can still call a deprecated function with params['version'] = 2, just that if I call it with version=3 then it wouldn't work, right?

I'm thinking that those old functions might continue to call BAO's/DAO's but that nobody is guaranteeing those BAO's to still work the same way? Is that going to cause problems? An alternative would be to offload the compatibility to the API layer, so that if I call it with version=2 the API somehow figures out how to call the current version of the same API call but with the appropriate params and transformations. That can get complicated obviously, but maybe the path of least resistance?

For elegance I might argue to use a more objecty approach but probably doesn't fit in the overall architecture. Using the proposed route where you construct a path based on parameters, from a security standpoint you might want to have some checks. At the least don't allow ".." or path separators in them. And function_exists($function).

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Versioning
November 23, 2010, 02:25:57 pm
Code: [Select]
you are still intending to distribute the old v2 folder with every new release so we can still call a deprecated function with params['version'] = 2, just that if I call it with version=3 then it wouldn't work, right?
Yes

Quote
you are still intending to distribute the old v2 folder with every new release so we can still call a deprecated function with params['version'] = 2, just that if I call it with version=3 then it wouldn't work, right?

I'm imagining people wouldn't need to have the version (folder) in their require_once string but the $param['version'] would determine which function is called. If you don't pass in a version the default (for now) would be v2. If you are already calling the v2 code directly then no change.

Quote
but that nobody is guaranteeing those BAO's to still work the same way?

To some extent the unit tests will pick up changes that cause failures. If we identify a change that affects the v2 API in a small way then we would probably tweak it but officially once a Contact api existed for v3 then the v2 one would not be officially supported and the message would be to upgrade.

We would in essence be phasing out v2 rather than completely replacing it for 2 reasons
1) not to break anything that is still working just fine, since we don't want to piss people off if we don't have to
2) because in reality we won't get all the API fixed & upgraded all at once - at the moment if I am working on contribute api it's probably easier for me to upgrade it to use the basic v3 standards than to get my head around it's specific idiosyncracies but hard for me to know how to submit if for core - so part of what we want is to make it easy for people to help with the code.


Quote
At the least don't allow ".." or path separators in them. And function_exists($function).

Good point!
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Versioning
January 04, 2011, 07:22:59 pm
So,

I decided to try to get the test suite to work against v3 & hit a problem with versions + Civi + tests.

Civi actually calls the API quite a number of times and every API call is currently hardcoded to v2. The particular example I hit was an obscure API which appears to have been slightly renamed in v3 (unless I did it by accident)

civicrm_activity_processemail

In calling this

function parseMailingObject( &$mail ) in Utils/Mail/Incoming.php gets called which has
        require_once 'api/v2/Activity.php';
which causes a fatal error if you have already loaded (to test)
        'api/v3/Activity.php';

as they have the same functions in them.

In this case neither of the requires in Incoming.php seem to be required from eyeballing the code & commenting them out doesn't seem to trigger any errors
    //require_once 'api/v2/Activity.php';
     //   require_once 'api/v2/Contact.php';


However, it does highlight that we need a plan for upgrading the Core with the new version - possibly by setting a constant & calling each function with it as the version. We'd need to be able to set it & change it in the test suite so we can test 2 versions in the same run


http://wiki.civicrm.org/confluence/display/CRMDOC33/Upgrading+api%27s+from+v1+to+v2
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Versioning
January 09, 2011, 03:37:22 am
After going through most of the tests there don't seem to be too many conflicts - except for

CRM_Contact_BAO_Group

which calls the deprecated civicrm_contact_search function from v2/api

I would think these can be replaced by BAO only calls.

(as an aside I couldn't get CustomValueContactTypeTest to work for v2 or v3 - it didn't seem to like the Contact & Custom classes)
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Versioning

This forum was archived on 2017-11-26.