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) »
  • Common naming convention for API functions
Pages: [1]

Author Topic: Common naming convention for API functions  (Read 6634 times)

cap10morgan

  • I post occasionally
  • **
  • Posts: 56
  • Karma: 9
Common naming convention for API functions
March 23, 2009, 04:11:46 pm
The REST API interface makes some assumptions about the function naming convention that just don't hold up. But it would be great if they did! I'm writing some REST API client modules in other languages (mainly Ruby and Perl right now), and it's much easier to generate the URL from an autoloader-type method so you can do things like (examples in Perl):
$civicrm->contact_get($params);
or
$civicrm->activity_create($params);
without having to actually write each of those methods in the client. This keeps the client smaller, simpler, easier to maintain, and much more future-proof since you don't have to explicitly add every API function to the client libraries.

When I auto-generate a URL from the above Perl method call examples, I get rest.php?q=civicrm/contact/get&... and rest.php?q=civicrm/activity/create&... which both work fine. But stay tuned...

The REST interface code assumes that when you ask for rest.php?q=civicrm/foo/get you want the civicrm_foo_get function in api/v2/Foo.php. You can also ask for rest.php?q=civicrm/foo_bar/get and you'll end up with the civicrm_foo_bar_get function in api/v2/FooBar.php. It requires that you always have exactly 3 arguments.

This works fine for many functions, but it breaks on some important ones too. For instance, it works on civicrm_activity_create (as q=civicrm/activity/create) but doesn't work on civicrm_activity_get_contact (as q=civicrm/activity_get/contact). But that second format does work for civicrm_group_contact_add (as q=civicrm/group_contact/add). It's also putting resource type names and operation identifiers all over the place with little consistency.

So currently there's no way to automatically convert a method name to a URL because the naming is somewhat arbitrary. If we could define some simple rules for it, it would make using the API a much more pleasant experience (both directly and because it would enable the writing of simpler, more future-proof client libraries).

Ideally we would have a true REST interface (URLs are resources, operations are represented by the HTTP verb sent, etc.) but that would be a lot of work. So for now I'd suggest the following convention:

1. All API function names begin with civicrm_ like they do now.
2. The next part of the function name represents the resource type and is an underscore-separated representation of the php filename in which the function resides (so that civicrm_foo_bar_get MUST be defined in api/v2/FooBar.php because "foo_bar" is converted to "FooBar".
3. The last part of the function name represents the operation (i.e. "get", "delete", "create", etc.). This part MAY NOT contain an underscore (otherwise it would be very hard to tell where you switched from resource type to operation identifier when parsing).

Then, when generating URLs, you stick to the requirement that only ever be 3 slash-separated arguments, and the first one is always "civicrm". So you always have rest.php?q=civicrm/ at the beginning. Then in the 2nd argument you put in the underscore-separated resource type / filename identifier. In the 3rd and last part you put in the operation identifier.

So for our two slightly more complex examples above, you'd have to rename the civicrm_activity_get_contact function to civicrm_activity_contact_get and put it in a separate file called api/v2/ActivityContact.php. It would just work for civicrm_group_contact_add since that follows these rules already.

Does this seem like a reasonable requirement to impose? We could write backwards-compatibility wrapper functions to call the new ones (and ideally spit out a deprecation warning) anywhere we had to rename a function.

cap10morgan

  • I post occasionally
  • **
  • Posts: 56
  • Karma: 9
Re: Common naming convention for API functions
March 24, 2009, 09:28:21 am
Lobo gave me the go-ahead for this for 2.3 (so working on trunk now). I'll need the devs and community's help to enforce this down the road.

So starting now, if you see an API function added (or an existing one) that doesn't conform to this rule, please report it as a bug.

The rule is: The function name must follow the pattern "function civicrm_resource_name_op( $params )" and it MUST live in a file in api/v2/ called ResourceName.php.

Example #1: I will be renaming civicrm_activities_contact_get to civicrm_activity_contact_get and moving it to a new file called ActivityContact.php (it's currently in Activity.php).

Example #2: I will be renaming civicrm_activity_get_types to civicrm_activity_type_get and moving it to a new file called ActivityType.php (also currently in Activity.php).

cap10morgan

  • I post occasionally
  • **
  • Posts: 56
  • Karma: 9
Re: Common naming convention for API functions
April 22, 2009, 07:37:35 pm
I've posted this to the wiki here: http://wiki.civicrm.org/confluence/pages/viewpage.action?pageId=15401593

cap10morgan

  • I post occasionally
  • **
  • Posts: 56
  • Karma: 9
Re: Common naming convention for API functions
May 04, 2009, 09:12:00 am
This has been updated based on meetings we had about the API at the CiviCRM Dev Camp in San Francisco. We've added some function orthogonality and behavior characteristics to the standard. Same wiki page: http://wiki.civicrm.org/confluence/pages/viewpage.action?pageId=15401593

dharmatech

  • I post frequently
  • ***
  • Posts: 280
  • Karma: 53
    • dharmatech.org
Re: Common naming convention for API functions
May 04, 2009, 12:58:45 pm
That's a straightforward approach.  But, one of the goals of an API definition is to maintain a consistent way to talk to the system as the system internals change.  In other words, if we treat a "resource" in the above definition as just the external representation of a BAO, we introduce two problems:

  • Any system internal change that affects BAO definitions will appear to the outside as a change in the API definition
  • Any DBMS operation that requires atomic access to more than one table will be hard to do through the API since multiple REST operations will be needed and there is not a way to guarantee atomicity of multiple operations.
So, we also need to think about how to handle those situations.

-- Walt
 
http://dharmatech.org
oss@dharmatech.org
801.541.8671

cap10morgan

  • I post occasionally
  • **
  • Posts: 56
  • Karma: 9
Re: Common naming convention for API functions
May 04, 2009, 01:17:18 pm
Quote from: dharmatech on May 04, 2009, 12:58:45 pm
That's a straightforward approach.  But, one of the goals of an API definition is to maintain a consistent way to talk to the system as the system internals change.  In other words, if we treat a "resource" in the above definition as just the external representation of a BAO, we introduce two problems:

  • Any system internal change that affects BAO definitions will appear to the outside as a change in the API definition

I see your point, but I don't think this is necessarily the case. If we treat the current set of API resources as our externally-exposed resource set, then we will just have to code interpretation layers between this static set and the underlying BAO changes that will inevitably happen down the road. That could get hairy in some instances, but I think we can manage it. So yes, the API layer's code will get more complex as we add more interpretations between "the way we used to do it" and "the way we do it now," but I think we can learn from all that and come up with an even better API design and implementation for the 3.x series (and hopefully keep that frozen for the 3.x lifetime too). Do you agree?

Quote
  • Any DBMS operation that requires atomic access to more than one table will be hard to do through the API since multiple REST operations will be needed and there is not a way to guarantee atomicity of multiple operations.
So, we also need to think about how to handle those situations.

-- Walt
 

Another idea that came out of the API meetings at Dev Camp was a way to call multiple API functions from the same REST call. That seems like a good idea for a number of reasons, and we could implement a transactional layer in the REST code over and above those API function calls (if one doesn't already exist) that checks for errors in any of the API call returns and rolls back the transaction if it sees any. So then we could say, "If you call multiple functions in the same REST call, they will be atomic." Does that solve this problem in your mind (theoretically at this point, since none of this code exists yet)?

acrosman

  • Guest
Re: Common naming convention for API functions
May 04, 2009, 01:42:16 pm
Wes, thanks for getting the ball rolling on these updates.  There are several factors I'd like to change about how the REST interface works that are separate from the API itself. I think it would be helpful if we talked about this as 2 parts: the API itself, the REST interface that wraps around it.  If we have consistent rules in the API, making them work sensibly over REST becomes much easier.  The REST interface has several sins in it that I would like to clean up (like returning multiple keys, unclear URL structure, everything is a GET, etc).  Some are my fault, some are inherited from the experimental interface I started with, but I'd like address as many as possible for 2.3.

I'll put together suggestions about that on the wiki soon, and provide a link here.  But unless others object, I'm inclined to think we should continue to treat the REST interface as just that; an interface to the underlying API.  Let's not get hung up here too much about the REST interface.  The API should be consistent no matter how you reach it.  I expect that it's no less frustrating if you're writing a module that works against a changing API than if you're working on an unrelated CMS.

cap10morgan

  • I post occasionally
  • **
  • Posts: 56
  • Karma: 9
Re: Common naming convention for API functions
May 04, 2009, 03:05:52 pm
Quote from: acrosman on May 04, 2009, 01:42:16 pm
Wes, thanks for getting the ball rolling on these updates.  There are several factors I'd like to change about how the REST interface works that are separate from the API itself. I think it would be helpful if we talked about this as 2 parts: the API itself, the REST interface that wraps around it.  If we have consistent rules in the API, making them work sensibly over REST becomes much easier.  The REST interface has several sins in it that I would like to clean up (like returning multiple keys, unclear URL structure, everything is a GET, etc).  Some are my fault, some are inherited from the experimental interface I started with, but I'd like address as many as possible for 2.3.

Great, that all seems good.

Quote
I'll put together suggestions about that on the wiki soon, and provide a link here.  But unless others object, I'm inclined to think we should continue to treat the REST interface as just that; an interface to the underlying API.  Let's not get hung up here too much about the REST interface.  The API should be consistent no matter how you reach it.  I expect that it's no less frustrating if you're writing a module that works against a changing API than if you're working on an unrelated CMS.

I'm not clear on what exactly you're recommending here. Where are we getting "hung up" on the REST interface?

I think it's mainly that most of us who are interested in the API are also interested in the REST interface because that's how we want to access the API. So we want to work on / improve both at the same time. But I think we're doing a good job of maintaining the logical separation between the two. Do you disagree?

I don't think we're going to let the (perceived or real) shortcomings of the REST interface hold us back from improving and documenting the API, but we do want to address the shortcomings of the REST interface on the same or similar timeline. I'm inclined to let you take the lead on that now since you designed and built it and have good ideas for how to improve it. But there are also some ideas coming from this group (such as the more than one API call per REST call / transactional integrity idea) which are good and we'd like to at least discuss here. (Or, to be more correct, the use cases those ideas cover are valid and common and we should discuss how we will accommodate them in the REST interface at some point soon.) Seem right?

acrosman

  • Guest
Re: Common naming convention for API functions
May 04, 2009, 06:07:01 pm
Quote from: cap10morgan on May 04, 2009, 03:05:52 pm
I'm not clear on what exactly you're recommending here. Where are we getting "hung up" on the REST interface?

I think it's mainly that most of us who are interested in the API are also interested in the REST interface because that's how we want to access the API. So we want to work on / improve both at the same time. But I think we're doing a good job of maintaining the logical separation between the two. Do you disagree?

I think this conversation has been fine, but I think it'll be hard to maintain a separation of the two layers if they are discussed in the same place.

Quote from: cap10morgan on May 04, 2009, 03:05:52 pm
I don't think we're going to let the (perceived or real) shortcomings of the REST interface hold us back from improving and documenting the API, but we do want to address the shortcomings of the REST interface on the same or similar timeline. I'm inclined to let you take the lead on that now since you designed and built it and have good ideas for how to improve it. But there are also some ideas coming from this group (such as the more than one API call per REST call / transactional integrity idea) which are good and we'd like to at least discuss here. (Or, to be more correct, the use cases those ideas cover are valid and common and we should discuss how we will accommodate them in the REST interface at some point soon.) Seem right?

Yes.  I just want to make sure we pay attention to both sets of issues.  I think there are definitely issues that overlap, like Walt's comments you make reference too.  The two issues can't be handled totally independently, but I'm just worried that if you hold one conversation we'll lose details from one problem in the other.  I wasn't trying to shut anything down.

acrosman

  • Guest
Re: Common naming convention for API functions
May 04, 2009, 07:54:10 pm
I've posted my first pass at suggestions to improve the REST interface on the wiki:
http://wiki.civicrm.org/confluence/display/CRM/REST+Interface+Improvements

Please feel free to comment/criticize/improve.

acrosman

  • Guest
Re: Common naming convention for API functions
May 06, 2009, 05:38:50 pm
Jim Taylor left a comment on the wiki page making a suggestion about how to handle custom additions to the API.  I've been trying to think about ways that we might be able to address Walt's suggestion about making it possible to combine multiple API calls in one atomic REST call. 

Would it be reasonable to design a system that would allow for custom additions to the API that could be called through the REST interface as a means of handling Walt's idea?  If the REST interface called custom API add-ons, advanced users could then add functions to the API as needed.  Walt would this work for you, or do we need something else?  If not, can you give an example of what you're thinking of?

dharmatech

  • I post frequently
  • ***
  • Posts: 280
  • Karma: 53
    • dharmatech.org
Re: Common naming convention for API functions
May 11, 2009, 08:42:45 am
Most of what we do here involves function calls to the API, not URL references, so the idea of dropping a class definition file into a standard directory should be a good approach.  The CRM_Core_Transaction class creates a singleton object that apparently deals correctly with transactions nested within transactions so that shouldn't cause problems.

-- Walt
« Last Edit: May 11, 2009, 09:43:55 am by dharmatech »
http://dharmatech.org
oss@dharmatech.org
801.541.8671

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

This forum was archived on 2017-11-26.