INVALID_ARGUMENT exception when requesting Google's knowledge graph API - api

I've read the documentation on Google's knowledge graph and from what I understand we can search for results both based on a query and based on IDs. For getting results by a query, no problem whatsoever, but when I try to retrieve them by IDs, it fails. Setting aside what query I used myself, this is the request URL I got from Google's API Explorer:
https://kgsearch.googleapis.com/v1/entities:search?ids=kg%3A%2Fm%2F01nrz4&key={YOUR_API_KEY}
and the result is:
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT"
}
}
And I'm pretty sure that the problem is with the ids parameter. Am I missing something?
Thanks

OK, so here's the thing. Each found instance has an attribute like this: "#id": "kg:/m/0gkg6" . So in this instance the id is kg:/m/0gkg6, but when we want to run a query based on ID, we should omit the kg: part.

Related

Microsoft Graph API odata $filter query does not appear to work

I am trying to filter a set of data returned by the MS Graph API's managedDevices endpoint using an odata filter.
Sending the request without a filter gets the expected result.
GET https://graph.microsoft.com/beta/deviceManagement/managedDevices
returns this response:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#deviceManagement/managedDevices",
"#odata.count": 5,
"value": [
{
"id": "kj23kj4-0d47-34f3-8ff0-6b5sdfsdf3332f",
"userId": "asdfasw-1b48-436d-aa42-3werwer2344",
"deviceName": "some_device_name_9/16/2020_6:31 PM"
...
When I send any of the following requests I get the exact same response with 5 results:
GET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$filter=id eq 'kj23kj4-0d47-34f3-8ff0-6b5sdfsdf3332f'
GET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$filter=id in ('lksjdf...','qwerqwer...')
GET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$filter=ownerType ne 'personal'
I didn't see this listed on uservoice as an issue others are having specifically. They also apparently don't explicitly call out what odata query params are and aren't supported for specific endpoints. $select, for example, does work on this endpoint.
For this problem, I test it in my side also can't do the filter. And the odata url is correct, so I think the field id just not be designed to do filter.
If you want to do filter with id, you can use https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/{id} directly. It can get the result with specific "id", maybe it is why the field id not be designed to do filter.

How to filter group members in Microsoft graph API?

I was sure about after reading Microsoft document that I can filter the group members using OData Query Parameters because https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/group_list_members
Request GET URL - https://graph.microsoft.com/v1.0/groups/{groupId}/members?filter= startswith(givenname,'V')
In above URL groupId is used from https://graph.microsoft.com/v1.0/groups
but when I try to get the result using Graph Explorer (https://developer.microsoft.com/en-us/graph/graph-explorer) using my work account login, it's not working.
Also I have tried to use this in SDK (I have implemented graph API in my code using Microsoft graph API SDK) and still got same error.
And gives below error -
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "The specified filter to the reference property query is currently not supported.",
"innerError": {
"request-id": "96f3ffef-56f5-42e3-82f2-64813106b729",
"date": "2018-02-13T10:59:39"
}
}
}
Is this because "members" is not a resource type ? so it does not have properties and so we can not filter this result ?
If so then is there any other way we can get filtered group members ?
Also posted issue on Github - https://github.com/microsoftgraph/microsoft-graph-docs/issues/2239
Add ConsistencyLevel: eventual to Your request header (should work for v1.0 and beta as well)
Filtering of group members is now available as a beta API.
GET https://graph.microsoft.com/beta/groups/{id}/members?$count=true&$filter=startswith(displayName, 'a')
Here's how you would impelment it in code
//testing the filter query here
// Get groups user is a member of
// GET /me/memberOf
var myfilteredUserGroups = await _graphClient.Me.MemberOf
.Request(queryOptions)
.Header("ConsistencyLevel", "eventual")
.Filter("startswith(displayName, 'sa')")
.Select("displayName,groupTypes,id")
.Top(GraphConstants.PageSize)
.GetAsync();
// This method casts the returned DirectoryObjects
// as Group object, and filters out any non-Group objects
model.MyFilteredGroups = await GetAllPagesAsType<Group>(
_graphClient, myfilteredUserGroups);
return View(model);

Mailchimp API v2.0 filter campaigns by list id doesn't filter if there is no match

http://apidocs.mailchimp.com/api/2.0/campaigns/list.php
I would expect that something like
{
"apikey": "12345",
"filters": {
"list_id": "abcde",
"exact": true
}
}
to return a list of total=1 if there is one campaign with list_id = "abcde", or total=0 if there isn't (using exact=true). However, instead I get the full list. Is this by design? Am I missing some other setting to filter out all mismatches? Is there a way to deal with this?
OK, so this is what I have come up with, barring some other resolution:
When the result set is returned, do a sanity check on the first result (data.data[0]).
If there is a true match, then data.data[0].list_id = list_id
If there was no match, and the full set has come back, then data.data[0].list_id cannot = list_id
This extra step is not ideal, imo, but it does do the trick.
if data.data[0].list_id === list_id
// the list is a match, return the results
else
// the list is not a match, do something else
Here's another solution:
The full-response will provide an error object if no match
"errors": [{
"filter": "list_id",
"value": "abcde",
"code": 200,
"error": "Invalid MailChimp List ID: abcde"
}]
and an empty object for a set of matches
"errors": []
So you can first process your result by looking for this error object and making the appropriate decision.
I received some clarification from MailChimp (and post it here with permission) that this is as-intended:
To provide some more information, the behavior with the campaigns/list call completing, even with an invalid filter, is expected behavior. As you mention, an error array is included in the return, and it would be possible to check that array for any errors received to determine whether or not the call completed as expected.
I can certainly see how that may be unexpected, to receive the full list of campaigns when attempting to filter. If you'd prefer that an error would be returned, without the campaign data returned, we'd recommend adding that suggestion to our feedback form here: http://mailchimp.com/contact/feedback/ That's certainly something our developers could consider for future versions of the API.
I'm still not sure why they do it this way, but I've added feedback suggesting that they return an empty result (so as not to bulk up the response with irrelevant data), or to improve the documentation.

RESTful API - Correct behaviour when spurious/not requested parameters are passed in the request

We are developing a RESTful api that accepts query parameters in the request in the form of JSON encoded data.
We were wondering what is the correct behaviour when non requested/not expected parameters are passed along with the required ones.
For example, we may require that a PUT request on a given endpoint have to provide exactly two values respectively for the keys name and surname:
{
"name": "Jeff",
"surname": "Atwood"
}
What if a spurious key is passed too, like color in the example below?
{
"name": "Jeff",
"surname": "Atwood",
"color": "red"
}
The value for color is not expected, neither documented.
Should we ignore it or reject the request with a BAD_REQUEST 400 status error?
We can assert that the request is bad because it doesn't conform to the documentation. And probably the API user should be warned about it (She passed the value, she'll expects something for that.)
But we can assert too that the request can be accepted because, as the required parameters are all provided, it can be fulfilled.
Having used RESTful APIs from numerous vendors over the years, let me give you a "users" perspective.
A lot of times documentation is simply bad or out of date. Maybe a parameter name changed, maybe you enforce exact casing on the property names, maybe you have used the wrong font in your documentation and have an I which looks exactly like an l - yes, those are different letters.
Do not ignore it. Instead, send an error message back stating the property name with an easy to understand message. For example "Unknown property name: color".
This one little thing will go a long ways towards limiting support requests around consumption of your API.
If you simply ignore the parameters then a dev might think that valid values are being passed in while cussing your API because obviously the API is not working right.
If you throw a generic error message then you'll have dev's pulling their hair out trying to figure out what's going on and flooding your forum, this site or your phone will calls asking why your servers don't work. (I recently went through this problem with a vendor that just didn't understand that a 404 message was not a valid response to an incorrect parameter and that the documentation should reflect the actual parameter names used...)
Now, by the same token I would expect you to also give a good error message when a required parameter is missing. For example "Required property: Name is missing".
Essentially you want to be as helpful as possible so the consumers of your API can be as self sufficient as possible. As you can tell I wholeheartedly disagree with a "gracious" vs "stern" breakdown. The more "gracious" you are, the more likely the consumers of your API are going to run into issues where they think they are doing the right thing but are getting unexpected behaviors out of your API. You can't think of all possible ways people are going to screw up so enforcing a strict adherence with relevant error messages will help out tremendously.
If you do an API design you can follow two path: "stern" or "gracious".
Stern means: If you do anything I didn't expect I will be mad at you.
Gracious means: If I know what you want and can fulfil it I will do it.
REST allows for a wonderful gracious API design and I would try to follow this path as long as possible and expect the same of my clients. If my API evolves I might have to add additional parameters in my responses that are only relevant for specific clients. If my clients are gracious to me they will be able to handle this.
Having said that I want to add that there is a place for stern API design. If you are designing in an sensitive domain (e.g. cash transactions) and you don't want to leave room for any misunderstanding between the client and server. Imagine the following POST request (valid for your /account/{no}/transaction/ API):
{ amount: "-100", currency : "USD" }
What would you do with the following (invalid API request)?
{ amount: "100", currency : "USD", type : "withdrawal" }
If you just ignore the "type" attribute, you will deposit 100 USD instead of withdrawing them. In such a domain I would follow a stern approach and show no grace whatsoever.
Be gracious if you can, be stern if you must.
Update:
I totally agree with #Chris Lively's answer that the user should be informed. I disagree that it should always be an error case even the message is non-ambiguous for the referenced resource. Doing it otherwise will hinder reuse of resource representations and require repackaging of semantically identical information.
It depends on your documentation.. how strict you want to be .. But commonly speaking, Just ignore it. Most other servers also ignore request parameters it didn't understand.
Example taken from my previous post
Extra Query parameters in the REST API Url
"""Google ignore my two extra parameters here https://www.google.com/#q=search+for+something&invalid=param&more=stuff"""
Imagine I have the following JSON schema:
{
"frequency": "YEARLY",
"date": 23,
"month": "MAY",
}
The frequency attribute accepts "WEEKLY", "MONTHLY" and "YEARLY" value.
The expected payload for "WEEKLY" frequency value is:
{
"frequency": "WEEKLY",
"day": "MONDAY",
}
And the expected payload for "MONTHLY" frequency value is:
{
"frequency": "MONTHLY",
"date": 23,
}
Give the above JSON schema, typically I will have need a POJO containing frequency, day, date, and month fields for deserialization.
If the received payload is:
{
"frequency": "MONTHLY",
"day": "MONDAY",
"date": 23,
"year": 2018
}
I will throw an error on "day" attribute because I will never know the intention of the sender:
frequency: "WEEKLY" and day: "MONDAY" (incorrect frequency value entered), or
frequency: "MONTHLY" and date: 23
For the "year" attribute, I don't really have choice.
Even if I wish to throw an error for that attribute, I may not be able to.
It's ignored by the JSON serialization/deserialization library as my POJO has no such attribute. And this is the behavior of GSON and it makes sense given the design decision.
Navigating the Json tree or the target Type Tree while deserializing
When you are deserializing a Json string into an object of desired type, you can either navigate the tree of the input, or the type tree of the desired type. Gson uses the latter approach of navigating the type of the target object. This keeps you in tight control of instantiating only the type of objects that you are expecting (essentially validating the input against the expected "schema"). By doing this, you also ignore any extra fields that the Json input has but were not expected.
As part of Gson, we wrote a general purpose ObjectNavigator that can take any object and navigate through its fields calling a visitor of your choice.
Extracted from GSON Design Document
Just ignore them.
Do not give the user any chance to reverse engineer your RESTful API through your error messages.
Give the developers the neatest, clearest, most comprehensive documentation and parse only parameters your API need and support.
I will suggest that you ignore the extra parameters. Reusing API is a game changer in the integration world. What if the same API can be used by other integration but with slightly extra parameters?
Application A expecting:
{
"name": "Jeff",
"surname": "Atwood"
}
Application B expecting:
{
"name": "Jeff",
"surname": "Atwood",
"color": "red"
}
Simple get application application A to ignore "color" will do the job rather to have 2 different API to handle that.

How to add content and moreDetailsUrl for Google Search suggest?

I'm using GSA (version 6.14) and we would like to get an auto suggest function on our website. Works fine for basic requests, but it seems the GSA offers more functionality when you would be using user-added results. However, I can find nowhere a reference on how to add user-added results.
This is what the information tells me today :
/suggest?q=<query>&max=<num>&site=<collection>&client=<frontend>&access=p&format=rich
should return a response as below :
{
"query": "<query>",
"results": [
{ "name": "<term 1>", "type": "suggest"},
{ "name": "<term 2>", "type": "suggest"},
{ "name": "<term 3>", "type": "uar", "content": "Title of UAR",
"moreDetailsUrl": "URL of UAR"}
]
}
I am able to get results as the first 2 lines, but would like to get results as the last line also, so with content and a moreDetailsUrl. So maybe a very stupid question but I am not able to find the answer anywhere : How and where do I add this UAR ?
I actually want to understand if it's feasible to get metadata into the content part of the JSON, so if for instance an icon meta is available I'd like to have it included in the JSON so I can enrich my search results.
User Added Results are a OneBox that can be added to multiple frontends. See this: https://developers.google.com/search-appliance/documentation/614/admin_searchexp/ce_improving_search#uar
When done with Suggest, the data is fed from user entering 'keymatches' directly. What's different about them is that they are a direct link versus a suggested query. If you use the out of the box experience, you'll click a link to the url instead of running another query.