How to make a GET request using a filter on a datetime property with EspoCRM REST API? - rest

EspoCRM provides a REST API that sadly has only incomplete documentation. Especially the filters that can be used with a GET request are not documented:
where - (array) filters;
From using Firebug I've discovered that a filter consists of three query parameters:
where[0][field]=somefield
where[0][type]=somoperator
where[0][value]=somevalue
Example, filter on name=Foo:
?where[0][field]=name&where[0][type]=equals&where[0][value]=Foo
The meaning of equals is not documented, as are the possible filter types.
Now I want to filter a collection on a datetime field modifiedAt. I have no idea what the proper values for type and value would be to find all entities that have been modified after a given datetime.
How can the EspoCRM REST API be used for this?

After playing around with the EspoCRM web GUI, I was able to make a search that uses the filter I need. The query parameters are:
where[0][type]=after
where[0][field]=modifiedAt
where[0][value]=2016-06-01 16:12:00
where[0][dateTime]=true
where[0][timeZone]=Europe%2FBerlin

Related

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

jcr sql-2 get node name

i am working on aem 6.3 and would like to get page name
SELECT * FROM [cq:Page] WHERE ISDESCENDANTNODE("/content/Product/Silhouettes/Accessories/Bands/Headband")
If I need to retrieve name of the nodes using sql-2 , how do I achieve it?
You can specify column constraints like title, node name, etc this way -
SELECT nodeSet.name, nodeset.title
FROM [cq:Page] AS nodeSet
WHERE ISDESCENDANTNODE("/content/Product/Silhouettes/Accessories/Bands/Headband")
Note: the query tool in AEM(Tools -> Query) will not list the query results according to the columns you've mentioned, it will only list the node paths.
You can look at using /etc/importers/bulkeditor.html or AEM fiddle tool to visualize the query results based on column constraints.
If you want to achieve this programmatically, you can use the same query as you've mentioned in your question and use javax.jcr.query.* and javax.jcr.Node.* API's to retrieve just about any property from the query result. This article here should help you achieve this programatically.
Use the ResourceResolver API to execute and obtain the query results:
final Iterator<Resource> pagesIterator = resolver.findResources('<your_query_here>', javax.jcr.query.Query.JCR_SQL2);
while (pagesIterator.hasNext()) {
final Resource pageResource = pagesIterator.next();
LOG.info(pageResource.getName());
}
However, please note that if you are using any version higher then CQ 5.6, you should use instead the Page API.
In this case, the listChildren(Filter<Page> filter, boolean deep) method will do the job.
The PageFilter parameter may be used if you want to filter through pages of some kind. So if no extra criteria for your page finding algorithm, your may pass null or a new empty object.
The boolean parameter: if false it returns only direct child pages, and if true would list all the descendant pages of the given page.
Therefore, the equivalent solution of the SQL Query which would provide you the same end results would be:
Iterator<Page> rootPageIterator = rootPage.listChildren(null, true);

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.

Rest API: How should the filter params send to API in case query based on nested resource

I have two entities Properties and Bookings.
I need to know the URL structure in case I'm filtering the properties base on query on bookings.
In my case I need to get the properties which are free (not occupied) at specific date.
Can it be
api/properties/free/{date}
Or
api/properties/bookings?bookingDate!='1-1-2017'
Or
api/properties?bookingDate!='1-1-2017'
it seems for me that the last one is the more appropriate but the filter is on the bookings not on the properties which is not obvious.
The Facebook Graph API has a interesting way of doing nested queries by using a strategy of fields filter.
The fields filter it´s a way of filter specific fields or nested fields of a rouserce. They also create a standard way to inform functions for every selected field like: limit or equal.
Your request would be something like this:
GET /api/properties?fields=bookings{bookingDate.notEqual('1-1-2017')}
For more information about Facebook´s GraphAPI:
https://developers.facebook.com/docs/graph-api/overview/