oData - how to use filter for specific odata.type - odata

My oData query is as follow.
http://localhost:21005/api/v1/Devices?$expand=Jobs
My oData JSON response (in Postman's Pretty format) is as follow.
{
"#odata.context": "http://localhost:21005/api/v1/$metadata#Devices",
_"value": [
{
"Id": "abc03c74-8697-49ec-85e6-6444112d0336",
"TimeOffset": 0,
"TimeOffsetMode": "Unmanaged",
"Jobs": [
{
"#odata.type": "#VT.Api.Models.GetDataJob",
"Id": "ba07d50a-f17d-4c65-b3cf-f3e03d1ba1cf"
},
{
"#odata.type": "#VT.Api.Models.GetDataProfilerJob",
"Id": "5aa9c046-e4f2-44de-b932-16c06b86b084"
},
{
"#odata.type": "#VT.Api.Models.GetDeviceConfigurationJob",
"Id": "d7dc0ac5-1f89-4356-aaa8-9ac40353e1af"
}
}
{
"Id": "d42ac1f0-1261-4100-8391-013a226ff25f",
"TimeOffset": 0,
"TimeOffsetMode": "Unmanaged",
"Jobs": [ ]
}
}
Now, I want to query for only specific "#oData.type"
For example, I just want all the "Jobs" whose data type is "#VT.Api.Models.GetDataJob" ("#odata.type": "#VT.Api.Models.GetDataJob"). What kind of filter or query should I use?

The query should be:
http://localhost:21005/api/v1/Devices?$expand=Jobs($filter=isof('VT.Api.Models.GetDataJob'))
but as Brad said, IsOf has not been implemented in webapi odata v4.

According to the current spec, the correct way would be to apply a type filter to the expand expression, e.g.:
http://host/service/Orders?$expand=Customer/Model.VipCustomer
or, using your example,
http://localhost:21005/api/v1/Devices?$expand=Jobs/VT.Api.Models.GetDataJob
Please note that this will return all devices, expand their Jobs association, and only add GetDataJob instances to the resulting association sets. If you only want to query devices that have GetDataJob instances, you will need to see if you can use lambdas with type filters.
See also this SO question and OData Version 4.0 Part 2: URL Conventions

According to the OData spec you should be able to use the "IsOf" function to accomplish this. However, I don't believe this has been implemented yet in WebApi OData v4 (assuming that's what you're using):
https://github.com/OData/WebApi/issues/185

Related

How can I filter calendar events with a specific email address or name using Microsoft graph api and OData?

I'm using the Microsoft graph api to fetch calendar events.
Now I would like to only fetch events where one of the attendees has a specific name or email address.
An example response describing such an event is
{
"subject": "General meeting",
"attendees": [
{
"emailAddress": {
"name": "Peter Pan",
"address": "peter.pan#neverland.org"
}
},
{
"emailAddress": {
"name": "Captain Hook",
"address": "captain.hook#neverland.org"
}
}
]
}
According to Microsofts documentation the likely way to achieve this is using OData and the any operator. However I can't find a way to access nested properties like name and address using query parameters.
I was hoping I could do something like this
https://graph.microsoft.com/v1.0/me/calendarview?startdatetime=2022-01-01T00:00:00.000Z&enddatetime=2022-31-01T00:00:00.000Z&$select=attendees,subject&$filter=attendees/any(var:var/emailAddress/address eq 'peter.pan#neverland.org')
but using subparam (emailAddress/address) like that leads to bad request.
If the emailAddress field was just an actual email and not another entity, filtering would work.
https://graph.microsoft.com/v1.0/me/calendarview?startdatetime=2022-01-01T00:00:00.000Z&enddatetime=2022-31-01T00:00:00.000Z&$select=attendees,subject&$filter=attendees/any(var:var/emailAddress eq 'peter.pan#neverland.org')
Is it possible to achieve what I want?
According this comment Graph API doesn't support drilling down multiple levels of relationships.

In Power Automate, is there a way to filter on a Custom Field using DevOp's Send HTTP Request?

I'm trying to use Power Automate to return a custom work item in Azure DevOps using the "workitemsearch" API (via the "Send HTTP Request" action). Part of this will require me to filter based on the value of a Custom Field, however, I have not been able to get it to work. Here is a copy of my HTTP Request Body:
{
"searchText": "ValueToSearch",
"$skip": 0,
"$top": 1,
"filters": {
"System.TeamProject": ["MyProject"],
"System.AreaPath": ["MyAreaPath"],
"System.WorkItemType": ["MyCustomWorkItem"],
"Custom.RequestNumber": ["ValueToSearch"]
},
"$orderBy": [
{
"field": "system.id",
"sortOrder": "ASC"
}
],
"includeFacets": true
}
I have been able to get it to work by removing the Custom.RequestNumber": ["ValueToSearch"] but am hesitant to use that in case my ValueToSearch is found in other places like the comments of other work items.
Any help on this would be appreciated.
Cheers!
From WorkItemSearchResponse, we can see the facets (A dictionary storing an array of Filter object against each facet) only supports the following fields:
"System.TeamProject"
"System.WorkItemType"
"System.State":
"System.AssignedTo"
If you want to filter RequestNumber, you can just set it in the searchText as the following syntax:
"searchText": "RequestNumber:ValueToSearch"

Nested query parameters in Swagger 2.0

I'm documenting a Rails app with Swagger 2.0 and using Swagger-UI as the human-readable documentation/sandbox solution.
I have a resource where clients can store arbitrary metadata to query later. According to the Rails convention, the query would be submitted like so:
/posts?metadata[thing1]=abc&metadata[thing2]=def
which Rails translates to params of:
{ "metadata" => { "thing1" => "abc", "thing2" => "def" } }
which can easily be used to generate the appropriate WHERE clause for the database.
Is there any support for something like this in Swagger? I want to ultimately have Swagger-UI give some way to modify the generated request to add on arbitrary params under the metadata namespace.
This doesn't appear supported yet (over 2 years after you asked the question), but there's an ongoing discussion & open ticket about adding support for this on the OpenAPI github repo. They refer to this type of nesting as deepObjects.
There's another open issue where an implementation was attempted here. Using the most recent stable swagger-ui release, however, I have observed it working as I expect:
"parameters": [
{
"name": "page[number]",
"in": "query",
"type": "integer",
"default": 1,
"required": false
},
{
"name": "page[size]",
"in": "query",
"type": "integer",
"default": 25,
"required": false
}
This presents the expected dialog box & works with Try it out against a working server.
I don't believe there is a good way to specify arbitrary or a selection of values (e.g. an enum), so you may have to add parameters for every nesting option.

Restricting results of $expand parameter in SensorThings API

I am attempting to truncate the results of an $expand parameter from SensorThingsAPI e.g.
http://example.org/v1.0/Things?$expand=Datastreams
However, $top only restricts the trunk of the query (e.g. Things). Is there a way to truncate the results of the 'leaves' of an $expand?
In this case, the server-side pagination should be controlling the 'leaves' of an $expand.
For example, if the service limit 100 entities for each response and the expanded entities (or the collection) have more than 100, the service will return the top 100 entities following a service-defined order. A #iot.nextLink will also be returned, so that the client know how to fetch the next 100 entities (i.e., next page). Using the above query as an example, an example nextLink to retrieve the Datastreams will be
Datastreams#iot.nextLink:"http://URL_to_retrieve_the_next_page/"
You can use this OGC SensorThings sandbox to see an example return of $expand: http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams?$expand=Observations
The following JSON shows an example response of the following query with $expand: http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams?$expand=Observations:
{
"#iot.count": 1,
"value": [{
"#iot.id": 8,
"#iot.selfLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)",
"description": "Daily Water level",
"observationType": "http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Observation",
"unitOfMeasurement": {
"symbol": "m",
"name": "meter",
"definition": "https://en.wikipedia.org/wiki/Metre"
},
"Observations#iot.nextLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/Observations?$top=3&$skip=3",
"Observations#iot.count": 1826,
"Observations": [{
"#iot.id": 1835,
"#iot.selfLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Observations(1835)",
"phenomenonTime": "2015-12-30T16:00:00.000Z",
"result": "1375.44",
"resultTime": null,
"Datastream#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Observations(1835)/Datastream",
"FeatureOfInterest#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Observations(1835)/FeatureOfInterest"
}],
"ObservedProperty#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/ObservedProperty",
"Sensor#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/Sensor",
"Thing#iot.navigationLink": "http://scratchpad.sensorup.com/OGCSensorThings/v1.0/Datastreams(8)/Thing"
},{},{}]
}

Restkit: How to get and map data from multiple source

I'm currently working on iOS Application with RestKit 0.20 to access data from Tastypie API.
And I am trying to get feeds data from URL like this
/api/v2/feed/?format=json
Then I will get array of feeds as below.
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [
{
"id": 1,
"info": "This is my first post",
"pub_date": "2013-02-03T15:59:33.311000",
"user": "/api/v2/user/1/",
"resource_uri": "/api/v2/feed/1/"
},
{
"id": 2,
"info": "second post, yeah",
"pub_date": "2013-02-03T16:00:09.350000",
"user": "/api/v2/user/1/",
"resource_uri": "/api/v2/feed/2/"
}
]
}
if I want to fetch more data about user which Tastypie send it as url like a foreign key "user": "/api/v2/user/1/", do I have to nested call objectRequestOperation.
I'm confusing because I'm using block to callback when data is successful loaded. So is there any better way than requesting user data again for each feed after requesting feed complete.
Thank you very much :)
You have to define in the Feed resource :
user = fields.ToOneField(UserResource, full=True)
More info in the tastypie doc http://django-tastypie.readthedocs.org/en/latest/resources.html
Why Resource URIs?
Resource URIs play a heavy role in how Tastypie delivers data. This can seem very different from other solutions which simply inline related data. Though Tastypie can inline data like that (using full=True on the field with the relation), the default is to provide URIs.
URIs are useful because it results in smaller payloads, letting you fetch only the data that is important to you. You can imagine an instance where an object has thousands of related items that you may not be interested in.
URIs are also very cache-able, because the data at each endpoint is less likely to frequently change.
And URIs encourage proper use of each endpoint to display the data that endpoint covers.
Ideology aside, you should use whatever suits you. If you prefer fewer requests & fewer endpoints, use of full=True is available, but be aware of the consequences of each approach.

Resources