CosmosDB pagination with requestContinuation not returning results - spring-data-jpa

I'm using JPA with CosmosDB to fetch entries from containers.
I have to implement pagination and, according to the documentation, it should rely on the requestContinuation string, which is null on the first request and not null afterwards.
To make things more simple, I created a basic app which calls the repository, takes the requestContinuation object and then makes a new request using it's value.
I have 8 objects in the CosmosDB container and the page size is 5. The first request returns 5 elements and the requestionContinuation value
{"compositeToken":"{\"token\":null,\"range\":{\"min\":\"\",\"max\":\"FF\"}}","orderByItems":[{"propertyBag":{"item":[2021,5,20,14,13,52,716826900]},"item":[2021,5,20,14,13,52,716826900],"map":{"item":[2021,5,20,14,13,52,716826900]}}],"rid":"7eYNAKj8mAMIAAAAAAAAAA==","inclusive":true}
I use it, AS IT IS, to make a new request
Pageable pageable = new CosmosPageRequest(0, size, requestContinuation, Sort.by(sort));
return repo.findAllByUserId(userId, pageable);
The result is empty and the new requestContinuation is null. The page object correctly states that the total number is 8 but never returns the missing 3.
The value of the requestContinuation is not a valid JSON, if you analyze it. I also tried replacing the \ from the compositeToken part of the JSON, which made it a valid JSON. If the invalid JSON is accepted by CosmosDB but the result is empty, the valid JSON is rejected as being INVALID :)
I looked into various sources and I saw something about encoding. I tried to URLEncoder class but it didn't work.
Does anybody have an idea?
Thanks.
UPDATE
The query is also sorting by the creation date. If sorting is removed, the new token works. It's structure is different.
Old token - with sorting:
{"compositeToken":"{\"token\":null,\"range\":{\"min\":\"\",\"max\":\"FF\"}}","orderByItems":[{"propertyBag":{"item":[2021,5,20,14,13,52,716826900]},"item":[2021,5,20,14,13,52,716826900],"map":{"item":[2021,5,20,14,13,52,716826900]}}],"rid":"7eYNAKj8mAMIAAAAAAAAAA==","inclusive":true}
New token - no sorting:
{"token":"+RID:~7eYNAKj8mAMKAAAAAAAAAA==#RT:1#TRC:5#ISV:2#IEO:65567#QCF:4#FPC:AQoAAAAAAAAADQAAAAAAAAA=","range":{"min":"","max":"FF"}}

The second request, with the continuationToken, was returning an empty response because the ordering field was a LocalDateTime field, which in CosmosDB is serialized as an array. I fixed the issue by adding this to the LocalDateTime field:
#JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss'Z'")
This way, the sorting field is a string and can be used for ordering.

Just Encode the Request Token and it will work like charm

Related

How to define id in POST request using Ravendb

Hello there
I'm having a trouble when I try to insert a document into a Ravendb Server which is running in my other computer. I can retrieve documents easily, but when I try to use REST API with POST request I get this error
"System.ArgumentException","Message":"Query string value 'id' must have a non empty value","Error":"System.ArgumentException: Query string value 'id' must have a non empty value
even though I have my Id defined like this:
{
"id":"adawd",
"name":"genereicname",
"password":"something"
}
Originally I'm making a flutter application but currently I'm just testing the API with Postman.
I messed around with id's (String, int) tried to leave it empty but no luck, does anyone know how to define Id for raven db to send me that sweet 200 response code...
According to the documentation you should use PUT to upload a new document or modify an existing one.
See: https://ravendb.net/docs/article-page/5.2/csharp/client-api/rest-api/document-commands/put-documents

Proper multi-id syntax when using the custom_file_ids[] query parameter for the CLIO API "contacts" endpoint

What is the correct API syntax for using the custom_file_ids[] query parameter to specify multiple fields (but not all) in the CLIO API contacts result set? I need to specify multiple custom fields. I can get it to work for a single field, but not multiple fields at the same time.
Specifically, how do I specify and delimit the multiple fields? I have tried the following:
custom_file_ids[]=1234567,2345678
custom_file_ids[]=[1234567,2345678]
custom_file_ids[]=(1234567,2345678)
custom_file_ids[]={1234567,2345678}
custom_file_ids[]=1234567:2345678
The API documentation at https://app.clio.com/api/v4/documentation is silent on the list syntax that it expects.
Below is one specific API call I tried (both the actual URL-encoded call, and a decoded one for clarity) using a simple comma-delimited list, but which only returns custom field data for the first ID in the list--not the second. If I enclose the ID list in any kind of brackets (per above), the endpoint returns a 404 error.
https://app.clio.com/api/v4/contacts?custom_field_ids[]=1234567%2C2345678&custom_field_values[4529224]=true&fields=id%2Cname%2Cprimary_address%2Cprimary_work_address%2Cis_client%2Ctype%2C%20primary_email_address%2Cprimary_phone_number%2Ccustom_field_values%7Bid%2Cfield_type%2Cfield_name%2Cvalue%2Ccustom_field%7D
https://app.clio.com/api/v4/contacts?custom_field_ids[]=1234567,2345678&custom_field_values[4529224]=true&fields=id,name,primary_address,primary_work_address,is_client,type,primary_email_address,primary_phone_number,custom_field_values{id,field_type,field_name,value,custom_field}
Try:
custom_file_ids[]=1234567&custom_file_ids[]=2345678
I was able to do this with Contacts Custom Fields by putting custom_field_id[] on the URL as many times as you have IDs.
I hope this helps.

Salesforce API - Using Compound fields. (Cannot deserialize instance of MailingAddress from VALUE_STRING)

Using REST API for Salesforce, I am trying to insert/update a contact into my business org where 'MailingAddress' is one of the fields with some set data, though in response I am getting this error message 'Cannot deserialize instance of MailingAddress from VALUE_STRING', the same response also resulting in 'OtherAddress'.
To my understanding, I think this is due to the reason that 'MailingAddress' and 'OtherAddress' are not actual fields that contains some String data, rather they take a dynamic address which resulting in filling up all other related fields like - 'MailingCity, MailingStreet, etc'.
So I have 2 questions:
1. How can I set 'MailingAddress' and 'OtherAddress' fields using API parameter only?
2. Is there any manual/documentation for this reference? As I am also having trouble with 'OtherLatitude' and 'OtherLogitude' fields.
Address and geolocation fields are compound fields.
You need to provide the value for the different components of the field, so for example, for MailingAddress you would need to provide MailingStreet, MailingCity, MailingState or MailingStateCode, etc. And for OtherAddress you would provide OtherStreet, OtherCity, etc.
For more information on compound fields: https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/compound_fields.htm

Clio API - What is the correct format to Update (PATCH) a custom field value for a matter

Anyone been able to successfully update the custom_field_values for a matter via Clio's API?
I'm trying to update the value for custom_field_values under a single matter. I'm able to send a JSON string using PATCH and update the default values for a matter like location or description using the following format
{"data":{"location":"Orange"}}
But when it comes to updating a "custom field value" I'm getting a 422 Unprocessable Entity error. I'm following Clio's v4 API Documentation and my understanding is that to update a custom_field_value you need the following JSON:
{"data":{"custom_field_values":[{"id":658213,"custom_field":{"id":139385},"value":"New Value Goes Here!"}]}}
However here is the message coming with the 422 error:
{"error":{"type":"ArgumentError","message":"An invalid argument was supplied: invalid custom field value id provided, acceptable format is <type>-<unique id>"}}
I can't interpret the part suggesting the acceptable format!
I've also tried sending the JSON in the following format which is closest to Clio's V2 API Docs for updating a custom field:
{"data":{"custom_field_values":[{"custom_field":{"id":139385},"value":"New value goes here"}]}}
But then this is what I get back:
{"error":{"type":"ArgumentError","message":"An invalid argument was supplied: custom field value for custom field 139385 already exists"}}
Please note that this is being tested in POSTMAN regardless of my development environment. I appreciate your response!
I've successfully created queries to update custom field values in matters many times, and these run all the time for me. I've compared your json to some examples of the json I'm successfully sending. Your syntax appears correct, but there's enough missing for me to only guess at where your mistake might be.
First, you're sending a PATCH to https://app.clio.com/api/v4/matters/{matter id}.json right? It took me a while to learn that you can't update the value of a matter's custom field with a query to https://app.clio.com/api/v4/custom_fields/{id}.json.
Second, just to clarify, the 658213 id you used above (the first id field) should be the unique id of this instance of your custom field. You won't get this until you've created an instance of the custom field particular to this matter. The second id field, where you've put 139385 is the id for the custom field itself, which you could get with a query to https://app.clio.com/api/v4/custom_fields.json.
If you're looking in the V.4 docs under Custom Fields, you won't find this, or at least I didn't. BUT you can find it in the intro section to the Matters portion fo the documentation: https://app.clio.com/api/v4/documentation#tag/Matters
Hope this helps. I'd imagine someone at Clio could help by verifying your error string is delivered when you have an incorrect custom field value unique id.
To further clarify Jacob's answer for everyone else:
custom_field{id} is the id given to a custom_field when it's created and will be the same for all matters or contacts it's used in.
custom_field_value{id} is the id given to an instance of the custom_field added to a particular matter and unique only to that matter
To add a custom_field to a matter for the first time the following format is used:
{"data":{"custom_field_values":[{"custom_field":{"id":123456},"value":"string or integer depending on the type of CF"}]}}
To update a custom field already added to a matter the following format should be used:
{"data":{"custom_field_values":[{"id":"text_line-1234567", "custom_field":{"id":123456},"value":"string or integer depending on the type of CF"}]}}
To delete a custom field already added to a matter the following JSON format is sufficient:
{"data":{"custom_field_values":[{"id":"text_line-1234567", "custom_field":{"id":123456},"_destroy":true}]}}
Format for updating a custom field already added to a matter:
{"data":{"custom_field_values":[{"id":"unique_instance_of_your_custom_field", "custom_field":{"id":'custom_field_id'},"value":"value which should be updated"}]}}
Here, the first id field should be the unique id of this instance of your custom field. To get this value follow this documentation section, app.clio.com/api/v4/documentation#tag/Matters and the second id field is the id for the custom field itself.

GET a resource filtering by a composite key as query parameter?

I'm thinking the best way to create an endpoint that one of the filters be a composite key.
Per example, we have a rest service to search for orders:
/orders/
We can filter the orders by start and final date:
/orders?dt-start=2017-05-11T17:12Z&dt-final=2017-05-11T17:12Z
Until here, so far so good. But I would like to filter the orders by customer. The customer is identified by his type of document and number of this document.
So, something like this could be possible:
/orders?type=ID&number=123456789
But the type and number are query parameters that only work together, it's a composite key. But using query parameter - like the last example - seems that the API user can do too:
/orders?number=123456789
/orders?type=ID
But not makes sense. Yes, I could return an error in response (bad request) if only one of these parameters were passed, but this is not natural for who are reading the API endpoint.
Another strategy is combine type and number in the same parameter, but I never see this in any API.
/orders?document=ID-12345678
It's odd to me too. I prefer to use separated parameters instead of this.
So, there are a way to use query parameter and solve this problem in a more "elegant" way?
Thanks!
Don't make up a composite key, instead conditionally require the two params. This ins't bad and IMO is much cleaner than creating a composite key which isn't represented by the data (or resource).
I've done this before, so to help illustrate I'll point you to it. This resource is to query for CyberFacts. The query is bound by a date range. To get data, you can do one of two things.
You can say ?today=true, and get the data for today (equivalent to saying ?startDate=2017-05-13&endDate=2017-05-13)
You can use the startDate and endDate query parameters, however if you use one and not the other (eg ?startDate=2017-05-13) you will receive a 400 Bad Request status response on the query and a error message in the response body.
So in this case I've done a few things to make this work
Make a higher priority parameter (today overrides startDate and endDate)
Document the valid behaviors
Provide appropriate error responses
For you only #2 and #3 would be needed, I think. Not knowing all of your use cases, I would suggest using /orders?type=ID&number=123456789 and document that number is a require query param when type=ID, and also include the appropriate error (eg: "You queried for an Order by Type 'ID', however you did not provide a 'number' query parameter")
How about providing a default value for type, (such as 'ID') as a fallback if the type parameter is absent (I'd probably go for the most common/used document type depending on your situation).
While for the number parameter I would enforce it, i.e. by specifying that it is a required parameter (somewhere in the docs?). If absent, return a bad request.