-> Expectation: Create a new record (since ID is not set)
-> Behaviour: Record was created
(return: JSON string with Inserted record)
-> Expectation on updating existing ID: Update existing record
-> Behaviour: Returned error message: {"error":"The request was not understood.","request":"POST /appdata/kid_SkYzM4SHM/games/12345"}
The most obvious CURL option for UPSERTs that should be used is probably "$ch, CURLOPT_CUSTOMREQUEST, 'PUT')" but it expects an ID to be sent otherwise error. In my case I don't want to send a unique _id and let Kinvey create one.
Is there something else I have to consider to make it work properly?
Regards
Best Answer
P
Pranav J
said
almost 3 years ago
Tayger,
I implemented your scenario and my observations are given below:
When making a PUT request, you will always have to provide an "_id" value.
If the "_id" is correct, it will update the record.
If the "_id" is not recognized (i.e. "_id" is wrong), it will create new record. If you provide your own "_id" like "12345" then a record with that "_id" will be created.
If you don't provide an "_id" value, you will always get an error because Kinvey always expects some "_id" value in "PUT /appdata/kid_xxxxxxxxx/mycollection/<_id>" . This is the required URL for PUT/ upsert.
You mentioned "In my case I don't want to send an unique _id and let Kinvey create one". In case of making a POST request, if an "_id" is specified in the request body, the entity is created with the supplied "_id". If an "_id" is not specified, one is automatically generated. Following is the detailed explanation:
I implemented your scenario and my observations are given below:
When making a PUT request, you will always have to provide an "_id" value.
If the "_id" is correct, it will update the record.
If the "_id" is not recognized (i.e. "_id" is wrong), it will create new record. If you provide your own "_id" like "12345" then a record with that "_id" will be created.
If you don't provide an "_id" value, you will always get an error because Kinvey always expects some "_id" value in "PUT /appdata/kid_xxxxxxxxx/mycollection/<_id>" . This is the required URL for PUT/ upsert.
You mentioned "In my case I don't want to send an unique _id and let Kinvey create one". In case of making a POST request, if an "_id" is specified in the request body, the entity is created with the supplied "_id". If an "_id" is not specified, one is automatically generated. Following is the detailed explanation:
Excellent and precise explanation that makes everything clear, thank you! I was not aware that sending an _id is mandatory using PUT. Working with POST offers both option and works great! It's just a pleasure working with Kinvey, removing all the "pain" I have with the big cloud providers!
T
Tayger
said
almost 3 years ago
Hmmm, I was a bit too quick. I just figured out that Kinvey doesn't like an existing _id in the sent JSON structure while using POST:
The Kinvey server encountered an unexpected error. Please retry your request","debug":"An entity with that _id already exists in this collection"}
The insert works fine if there is no '_id' with the sent _id value. The second time (after initial insert) I got the error message above.
Conclusion so far:
- Use POST for new records
- Use PUT for existing records (to be updated)
P
Pranav J
said
almost 3 years ago
Tayger,
Thanks for your kind words. You conclusion in the earlier comment is true.
Tayger
Hello
I'm building a set of CRUID functions based on PHP with CURL (https://secure.php.net/manual/de/function.curl-setopt.php) based on Kinvey's REST API.
In the end I would like to post it here for everyone but first they all need to work properly.
So far most functions work as they should. I'm struggling on the UPSERT (update/insert) functionality and can't find a proper way to make it work.
Pretty obvious I'm doing something wrong. My document source for this is from: https://devcenter.kinvey.com/rest/guides/datastore#modifiers
I have tried to find a proper way to make UPSERT working but no option seems to be reliable.
The tests I've done are all processed with these base CURL settings:
curl_setopt ($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json","Authorization: Kinvey ".<currentauthtoken>, "X-Kinvey-API-Version: 3" ));
curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode(<myInsUpdJson>) );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
Based on the documentation I should use 'PUT' for UPSERT operation. Just because I coudln't make it work I've tried all available CURL options:
- curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'PUT'); // based on documentation
- curl_setopt($ch, CURLOPT_PUT, true); // based on documentation
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_HTTPGET, true);
Furthermore I have tested the INSERT and UPDATE behaviour based on the 4 mentioned settings:
- Force INSERT with no ID set: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/")
- Force UPDATE on existing record with ID = 12345: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/12345")
Here are the results depending on using the 4 mentioned operator settings each with INSERT and UPDATE:
Using: curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'PUT') :
Sending no ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/")
-> Expectation: Create a new record (since ID is not set)
-> Behaviour: Returned error message: {"error":"The request was not understood.","request":"PUT /appdata/kid_xxxxxxxxx/mycollection/"}
Sending ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/12345")
-> Expectation on new ID: Create new record
-> Behaviour: New record created
(return: complete inserted record)
-> Expectation on updating existing ID: Update existing record
-> Behaviour: Existing record updated
(return: complete updated record)
Using: curl_setopt($ch, CURLOPT_PUT, true) :
Sending no ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/")
-> Expectation: Create a new record (since ID was not set)
-> Behaviour: Returned error message: {"error":"The request was not understood.","request":"PUT /appdata/kid_xxxxxxxxx/mycollection/"}
Sending ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/12345")
-> Expectation: Create a new record (since ID is not set)
-> Behaviour: A record was created but only with _id, _act, _kmd
(return: JSON string with only _id, _act and _kmd) - all other columns are empty
-> Expectation on updating existing ID: Update existing record
-> Behaviour: Update existing record (all columns expect _id, act_, _kmd are emptied)
(return: JSON string with only _id, _act and _kmd)
Using: curl_setopt($ch, CURLOPT_POST, true) :
Sending no ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/")
-> Expectation: Create a new record (since ID is not set)
-> Behaviour: Record was created
(return: JSON string with Inserted record)
Sending ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/12345")
-> Expectation on updating existing ID: Update existing record
-> Behaviour: Returned error message: {"error":"The request was not understood.","request":"POST /appdata/kid_SkYzM4SHM/games/12345"}
Using: curl_setopt($ch, CURLOPT_HTTPGET, true) :
Sending no ID: curl_setopt ($ch, CURLOPT_URL, "https://baas.kinvey.com/appdata/kid_xxxxxxxxx/mycollection/")
-> Expectation: Create a new record (since ID is not set)
-> Behaviour: Record was created
(return: JSON string with Inserted record)
-> Expectation on updating existing ID: Update existing record
-> Behaviour: Returned error message: {"error":"The request was not understood.","request":"POST /appdata/kid_SkYzM4SHM/games/12345"}
The most obvious CURL option for UPSERTs that should be used is probably " $ch, CURLOPT_CUSTOMREQUEST, 'PUT')" but it expects an ID to be sent otherwise error. In my case I don't want to send a unique _id and let Kinvey create one.
Is there something else I have to consider to make it work properly?
Regards
Tayger,
I implemented your scenario and my observations are given below:
When making a PUT request, you will always have to provide an "_id" value.
You mentioned "In my case I don't want to send an unique _id and let Kinvey create one". In case of making a POST request, if an "
_id"
is specified in the request body, the entity is created with the supplied "_id"
. If an"_id"
is not specified, one is automatically generated. Following is the detailed explanation:Please let me know if anything is unclear.
Thanks,
Pranav
Kinvey
- Oldest First
- Popular
- Newest First
Sorted by Oldest FirstPranav J
Tayger,
I implemented your scenario and my observations are given below:
When making a PUT request, you will always have to provide an "_id" value.
You mentioned "In my case I don't want to send an unique _id and let Kinvey create one". In case of making a POST request, if an "
_id"
is specified in the request body, the entity is created with the supplied "_id"
. If an"_id"
is not specified, one is automatically generated. Following is the detailed explanation:Please let me know if anything is unclear.
Thanks,
Pranav
Kinvey
Tayger
Hi Pranav
Excellent and precise explanation that makes everything clear, thank you! I was not aware that sending an _id is mandatory using PUT. Working with POST offers both option and works great! It's just a pleasure working with Kinvey, removing all the "pain" I have with the big cloud providers!
Tayger
Hmmm, I was a bit too quick. I just figured out that Kinvey doesn't like an existing _id in the sent JSON structure while using POST:
The Kinvey server encountered an unexpected error. Please retry your request","debug":"An entity with that _id already exists in this collection"}
The insert works fine if there is no '_id' with the sent _id value. The second time (after initial insert) I got the error message above.
Conclusion so far:
- Use POST for new records
- Use PUT for existing records (to be updated)
Pranav J
Tayger,
Thanks for your kind words. You conclusion in the earlier comment is true.
Let me know if you have any other questions.
Thanks,
Pranav
Kinvey
-
Why am I getting "SignatureDoesNotMatch" error when uploading a file?
-
Why am I getting an "IncompleteRequestBody" error when sending a DELETE request?
-
Is there a default sort order to collections fetched without an explicit sort query?
-
Is it possible to set ACLs on all users so that only administrators can query for users (without dis
-
Flex SDK
-
Query Bug in Backend?
-
Can analytics data be retrieved via Java SDK or REST?
-
Accesing REST API from a server without a user?
-
What json is required to assign a user group either read/write?
-
LDAP Authorization
See all 120 topics