First of all, thanks so much for Services. It's really amazing how much you can do with it!
I understand your standpoint about providing core functionality without modification, but this is one place I have to disagree completely with that stance. When I create taxonomy term, I get a simple 1 or 2 or 0 back. It's not even encoded in JSON! This just seems really inconsistent with what everything else returns for successful creation (such as a file, comment, node, user, etc).
I am on a project right now where iPhones are creating taxonomy terms and then adding them to new nodes. I don't understand, without writing a custom service, how the iPhones are supposed to get the new TID of the term they just created to include in the new nodes they are about to create.
I'm too tired to write the patch now, but it would be a simple one-line fix:
taxonomy_save_term($term);
return $term->tid;
instead of:
return taxonomy_save_term($term);
Curious to hear feedback!
| Comment | File | Size | Author |
|---|---|---|---|
| #26 | taxonomy_resource.inc_.zip | 4.02 KB | hubobbb |
| #22 | services-return-tid-1539138-22.patch | 845 bytes | jhedstrom |
| #7 | Services-7.x-3.x-Return_TID-1539138-7.patch | 846 bytes | MD3 |
| #7 | Services-6.x-3.x-Return_TID-1539138-7.patch | 623 bytes | MD3 |
| #6 | Services-7.x-3.x-Return_TID-1539138-6.patch | 0 bytes | MD3 |
Comments
Comment #1
kylebrowning commentedI think this is doable, but it needs to wait till #1436366: Ability to version a resource lands because we cant change what gets returns as it might break peoples clients.
You however can alter the callback and then make it point to your own function.
Comment #2
MD3 commentedGreat! Just thought I would share my final code for future reference:
I'll try to keep an eye out for the resource versioning so I can submit a timely patch!
Comment #3
ygerasimov commentedThe time for the patch is now. @MD3 will you take care about it?
Comment #4
MD3 commentedygerasimov: would this weekend be fast enough?
Comment #5
ygerasimov commented@MD3 sure, take your time
Comment #6
MD3 commentedFinally had some time to submit a patch! This should be tested by the community, but I am using it on a production server right now.
Any suggestions on the services_error() ?
Comment #7
MD3 commentedThanks to @xjm had to relearn my git skills. Here's the patches.
Comment #9
MD3 commentedSo it looks like we need to update the automated tests to take in account that I am returning the TID now instead of 0, 1, or 2. Should I just submit a new patch that updates the .test as well?
Comment #10
kylebrowning commentedNo, update the tests in this patch.
Comment #11
kylebrowning commentedAlso I believe i said this before but you need to be using the version resource #1436366: Ability to version a resource
Comment #12
ygerasimov commentedKyle could you please clarify your point about version resource? What needs to be added?
#6 patches are 0 bytes.
Comment #13
kylebrowning commentedIt needs to look more like this, adhering to proper update hooks so that OLD API's do not break. I left the else out but you get the idea.
Comment #14
ygerasimov commentedKyle, can we not do in this way? I understand that it will be convenient to use versions for changes in our standard resources. But making new version for such kind small changes will lead us to big number of versions and it will mess everyone. I would suggest not to use versions in standard resources at all until the changes are really significant.
Comment #15
kylebrowning commentedThey work just like hook_update_N so i think its ok. Besides in a 4.x branch we can remove the updates and make them standard.
If we do not use versions then peoples clients will break as its changing what is returned from a method call. The only way around that is to add a parameter which I dont really like the idea of, do you?
Comment #16
ygerasimov commentedI don't like idea of parameter. Well for this particular case I wouldn't go for new version as this is so minor change. But you are welcome to add it. Would be nice example for other modules to see how new versions work.
Comment #17
kylebrowning commentedIts not about how minor it is. Apps right now are expecting 1,2 or 0.
We CANNOT under any circumstances change that as you could crash a feature in someones app, or a website communicating to another site or whatever anyone might be using this endpoint for.
I pretty much wrote the code for it in
#13 it just needs to be put into a patch.
Comment #18
marcingy commentedSo I would not see core services itself use versioning. Why you may ask, it makes code more difficult to maintain and it makes multiple versions of a method exist in reality. What I would say actually needs to happens is as follows
* Create a new 7.3.x releae which includes versioning, this will allow people to override services as they need
* Create a new 7.4.x branch which is used to clean up returns from services and starts to define 'standards' for returns.
Comment #19
kylebrowning commentedWont fix in 3.x but ive added it as a list of things to do for 4.x
Comment #20
tyler.frankenstein commentedWith 7.x-3.3 of the Services module, I am able to call the Taxonomy Term Create Resource with only a vid, and it will create an empty term in that vocabulary. I think this is because the call to $term->name = trim($term->name); in taxonomy_term_save returns an empty string for the term name.
When this empty term is created, I receive a response of 1, which indicates SAVED_NEW (which is technically true, but it is a term without a name).
After reading the comments above, I understand it is important to maintain the 0, 1 or 2 return value. But it seems like 0 would never be returned. Please correct me if I'm wrong, but I haven't been able to have the Taxonomy Term Create Service Resource return a 0, ever. (If this is indeed a bug, maybe it deserves its own issue?)
To maintain backwards compatibility, would this be acceptable to return a 0 correctly?
If that is code change is OK, I'd be happy to make a patch for it.
Can we also have the vid validated, and if it doesn't validate, return a zero (instead of throwing a 500 error)?
Thank you Services team for your awesome module!
Comment #21
MD3 commentedEDIT:I realized this needed a better explanation.
When I filed this bug, I was using Drupal 6.24 or 6.25 with Services 6.x-3.0 or 6.x-3.1 and a database that was functional, at best (0 and 'Male', 1 and 'Female' in the same column).
I would suggest that for the default version of taxonomy resource, we leave this alone as Kyle has expressed before. It's really bad to break the current API and could have a lot of consequences for a lot of people.
As for what the new versioned resource returns, we should just imitate /node on every aspect possible (headers, body, etc).
Comment #22
jhedstromRealizing this is for 4.x, here's a patch in the meantime for people using 3.x. Fixes a fatal error in #7 which called a non-existent method.
Comment #23
ygerasimov commentedI propose here to create new version of taxonomy resource that will be based on drupal_form_submit() like node resource instead of saving term via api. This will add all needed validations like empty term name, required variables etc.
Comment #24
kylebrowning commentedCleaning issue queue. If someone wishes to work on this, let me know by reopening this ticket.
Comment #25
logicp commentedDoes anyone else have any interest in this? It would be nice to not have to do an additional services call simply to retrieve the newly created TIDs, but I understand the need to maintain the expected functionality that the module has provided thus far. Are there any proposed alternatives? Perhaps an additional resource to be added to the Services Taxonomy API arsenal?
Comment #26
hubobbb commentedThank you #22 the patches's author. it works well .
Now I give mycode for anyone who want to reference。
I added UPDATE and DELETE function ,witch return tid. Hope can help you .
and also I give ajax case here .
Version : 7.x-3.17 , download the zip file,unzip it .dir ../modules/services/resources/taxonomy_resource.inc
JS code :
var vid=4;//taxonomy_vocabulary vid
//get token
$.ajax({
url: '/service/cytaxonomy/user/token',//this is my service url ,define yours in services
type: 'POST',
dataType: 'json',
error: function onErroru(data){
console.log("user connect cytaxonomy user fail");
},
success: function (data) {
usertoken=data.token;
//cases here :
//updateterm(103,"name","description",5,89,usertoken);
//deleteterm(106,usertoken);
}
});
//term api fn begin
//get term tree
function gettermtree(parent,usertoken){
var updatedata='vid='+vid+'&parent='+parent;
$.ajax({
url: '/service/cytaxonomy/taxonomy_vocabulary/getTree',
type: 'POST',
dataType: 'json',
data: updatedata,
error: function onError(data){
console.log("update taxonomy_vocabulary getTree fail:"+vid);
},
beforeSend: function (request) {
request.setRequestHeader('X-CSRF-Token', usertoken);
},
success: function (data){
console.log(data);
console.log(JSON.stringify(data));
}
});
}
//get tid infos
function getterm(tid){
$.ajax({
url: '/service/cytaxonomy/taxonomy_term/'+tid,
type: 'GET',
dataType: 'json',
error: function onErroru(data){
/* $("#newslisttips").find(".alert").attr("class","alert alert-danger");
$(".newslisttips-content").html("you have offline 。");*/
console.log("user connect get fail");
},
success: function (data) {
console.log(data);
}
});
}
//add new term
function addterm(name,description,weight,parent,usertoken){
var updatedata='term[vid]='+vid+'&term[name]=' + name +'&term[description]='+description+'&term[weight]='+weight+'&term[parent]='+parent;
$.ajax({
url: '/service/cytaxonomy/taxonomy_term',
type: 'POST',
dataType: 'json',
data: updatedata,
error: function onError(data){
console.log("update taxonomy_term fail:"+tid);
},
beforeSend: function (request) {
request.setRequestHeader('X-CSRF-Token', usertoken);
},
success: function (data){
console.log(data);
console.log("added result:"+JSON.stringify(data));
}
});
}
//update term
function updateterm(tid,name,description,weight,parent,usertoken){
var updatedata='term[vid]='+vid+'&term[name]=' + name +'&term[description]='+description +'&term[weight]='+weight+'&term[parent]='+parent;
$.ajax({
url: '/service/cytaxonomy/taxonomy_term/'+tid,
type: 'PUT',
dataType: 'json',
data: updatedata,
error: function onError(data){
console.log("update taxonomy_term fail:"+tid);
},
beforeSend: function (request) {
request.setRequestHeader('X-CSRF-Token', usertoken);
},
success: function (data){
console.log(JSON.stringify(data));
}
});
}
//delelte term
function deleteterm(tid,usertoken){
$.ajax({
url: '/service/cytaxonomy/taxonomy_term/'+tid,
type: 'DELETE',
dataType: 'json',
error: function onError(data){
console.log("DELETE taxonomy_term fail:"+tid);
},
beforeSend: function (request) {
request.setRequestHeader('X-CSRF-Token', usertoken);
},
success: function (data){
console.log("DELETE:"+JSON.stringify(data));
}
});
}
//term api fn end
Comment #27
tyler.frankenstein commented@adventurist I'd be open to some type of query string, e.g.
load_term=truebeing present in the POST URL to indicate a request to fully load the term upon creation.