How to use scopeDescriptor and subjectTypes in VSTS Graph api groups list query? - azure-devops

I am trying to resolve a particular VSTS group by name to retrieve the identityDescriptor property. Rather than query all groups and filter, I want to leverage the query parameters supported. Looking at VSTS Groups - List API, it supports the additional query parameters scopeDescriptor, and subjectType. However, I keep providing bad values for these parameters.
However, when I specify any combination of these I get 0 results. In addition, as soon as I add a scopeDescriptor, I hit an Microsoft.VisualStudio.Services.Graph.InvalidSubjectTypeException -> HTTP 400 Bad Request.
Questions:
What are examples of expected values for subjectTypes?
Edit 1
subjectTypes are not the actual type, but the subtype that prefixes the subject descriptor. For example -> vssgp,aadgp:
"subjectDescriptor": "vssgp.Dc0NDgzLTzQ1NwOTI5LTI0NTcwNDLTAtMwUy0xLTktMTAtMC0wMjgxNjcxNDU0OS0zMU1MTM3NDI0NS0yMjUzNzA0ODMtE"
What are examples of expected values for scopeDescriptor?
Example query urls:
- Working:
https://{account}.vssps.visualstudio.com/_apis/graph/groups?api-version=4.1-preview.1
- Working subjectTypes:
https://{account}.vssps.visualstudio.com/_apis/graph/groups?subjectTypes=vssgp&api-version=4.1-preview.1
- scopeDescriptor throws:
https://{account}.vssps.visualstudio.com/_apis/graph/groups?scopeDescriptor=collection&api-version=4.1-preview.1
https://{account}.vssps.visualstudio.com/_apis/graph/groups?scopeDescriptor=collection&subjectTypes=Microsoft.TeamFoundation.Identity&api-version=4.1-preview.1

You can get the scope descriptors for a project or a collection by making an api request to https://vssps.dev.azure.com/{organization}/_apis/graph/descriptors/{Id}(replace id with projectId if you want to get the scope descriptor for a project and so on).
For example if you want to get the scope descriptor for a project then simply replace the storage key in the request URL with the project Id and in response you get the scope descriptor. The scope descriptor has the following format scp.(long unique identifier).
P.S: More on how to get descriptors can be found here https://learn.microsoft.com/en-us/rest/api/azure/devops/graph/descriptors/get?view=azure-devops-rest-5.0. Remember storagekey can be substituted with projectid or collectionid to get specific descriptors.

Regarding subjectTypes, it is the group type, such as vssgp, aadgp, you can get it from descriptor value of each group.

Related

SAP CDS Odata URL in ADF

I am new to azure data factory (ADF) and trying to create a dataset from an Odata source. The only problem here is that the Odata URL was developed in SAP CDS and so has custom query options as shown below:
"http://XXXXXXX/ZC_XXX_TU_SR_ACTIVITY_CDS/ZC_XXX_TU_SR_Activity(p_warehouse='E065',p_from=datetimeoffset'2021-06-01T00:01:01',p_to=datetimeoffset'2021-08-11T23:01:01')/Set"
When choosing the path I expect only one path in the options but I get 2 - ZC_XXX_TU_SR_Activity and ZC_XXX_TU_SR_ActivitySet so I am unsure of which one to use even though I have tried both
When writing the query, I have tried:
?(p_warehouse='E065',p_from=datetimeoffset'2021-06-01T00:01:01',p_to=datetimeoffset'2021-08-11T23:01:01')/Set
?(p_warehouse='E065'&p_from=datetimeoffset'2021-06-01T00:01:01'&p_to=datetimeoffset'2021-08-11T23:01:01')/Set
?(p_warehouse=%27E065%27&p_from=datetimeoffset%272021-06-01T00:01:01%27&p_to=datetimeoffset%272021-08-11T23:01:01%27)/Set
I have also tried to use all 3 options without the '?', "()" and the '/Set' but I am still getting errors.
I get this error:
"query (p_warehouse='E065',p_from=datetimeoffset'2021-06-01T00:01:01',p_to=datetimeoffset'2021-08-11T23:01:01')/Set failed with status code InternalServerError and message SY/530An exception was raised."
I have run out of ideas now and don't know what else to do. Please help. Thanks!
Note: The OData connector copies data from the combined URL: [URL specified in linked service]/[path specified in dataset]?[query specified in copy activity source].
Here, I could see that you have the root path as http://XXXXXXX/ZC_XXX_TU_SR_ACTIVITY_CDS and the resource path as ZC_XXX_TU_SR_Activity or ZC_XXX_TU_SR_ActivitySet.
So, there is an issue passing the query in :
System Query Option :
System Query Options are query string options that a client may use to
alter the amount and order of data returned by an OData service for
the URL-identified resource. All System Query Options have a “$”
character before their names.
Custom Query Option:
Because the character "$" is reserved for system query options, custom
query options MUST NOT begin with it. A custom query option can start
with the “#” character, however this can cause custom query options to
clash with function parameter values supplied via Parameter Aliases.
This URL addresses, for example, give a ‘secURLtytoken' through a
custom query option.
This is for more information: URL Conventions (OData Version 3.0)

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

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.

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

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