How do i get name=status using json path ... problem here is key=2 is random number,,, is their any way to skip these random and read name
Am using rest assured ,,this is sample response on GET request
Response
{
"error": false,
"message": "",
"data": {
"2": {
"name": "No Status",
"protected": "1",
"id": "1",
"temporal_start": "0",
"temporal_end": "2147483647"
},
"3": {
"name": "Started",
"protected": "1",
"id": "2",
"temporal_start": "0",
"temporal_end": "2147483647"
},
}
}
my request code is
given()
.param("error", "false")
.when()
.get(URI)
.then()
.body("data.2.name", startsWith(No))
I've found a solution but it's not very elegant:
when().
get(URI).
then().
body("data.collect { it.value }.reverse()[0].name", equalTo("No Status")).
body("data.collect { it.value }.reverse()[1].name", equalTo("Status"));
Which can be simplified using root paths:
when().
get(URI).
then().
root("data.collect { it.value }.reverse()[%d].name").
body(withArgs("0"), equalTo("No Status")).
body(withArgs("1"), equalTo("Status"));
Explanation:
Since data is a JsonObject represented as a HashMap we run the collect method to return only the values of the Map as a List. Then we reverse the list since it seems like the last when running collect the resulting list will have the last value first. Then we get the first value from this list (data.2 in your example) and finally get the name.
Related
Got a small problem (I guess). I created c# rest web API on docker swarm environment. Rest API is working properly - tested via the postman. Then I tried to compose Hasura service on the same docker swarm environment. The console is working properly also. The problem is with query action.
Code:
Action definition:
type Query {
getWeatherForecast : [WeatherForecastResonse]
}
New types definition:
type WeatherForecastResonse {
date : String
temperatureC : Int
temperature : Int
summary : String
}
Handler:
http://{api ip}:{api port}/WeatherForecast
While trying to execute query:
query MyQuery {
getWeatherForecast {
temperature
summary
date
temperatureC
}
}
All I got from response is error with json:
{
"errors": [
{
"extensions": {
"internal": {
"error": "invalid json: Error in $: not enough input",
"response": {
"status": 405,
"body": "",
"headers": [
{
"value": "Mon, 14 Jun 2021 13:54:00 GMT",
"name": "Date"
},
{
"value": "Kestrel",
"name": "Server"
},
{
"value": "0",
"name": "Content-Length"
},
{
"value": "GET",
"name": "Allow"
}
]
},
"request": {
"body": {
"session_variables": {
"x-hasura-role": "admin"
},
"input": {},
"action": {
"name": "getWeatherForecast"
}
},
"url": "http://{api ip}:{api port}/WeatherForecast",
"headers": []
}
},
"path": "$",
"code": "unexpected"
},
"message": "not a valid json response from webhook"
}
]
}
I got desired response by using postman white calling: http://{api ip}:{api port}/WeatherForecast (GET method)
Where should I improve, to finally get desired result from rest api?
P.S. hasura version: v2.0.0-alpha.4 (tried also with v1.3.3)
UPDATE:
Released a new version of web API. Inside WeatherForecastController included a new method with POST attribute. Query remained the same, but now graphql query returns what I want.
So the question is: Is it possible to call/access web api methods with GET attribute with Hasura action query?
From the version v2.1.0 and above we can do this using the REST Connectors.Hasura Actions RESTConnectors Methods
Go to the Actions tab on the console and create or modify an action. Scroll down to Configure REST Connectors.
In the Configure REST Connectors section, click on Add Request Options Transform
Along with this you can do a lot of other configurations.
No, currently it's not possible, Hasura always makes POST requests to the action handler:
When the action is executed i.e. when the query or the mutation is called, Hasura makes a POST request to the handler with the action arguments and the session variables.
Source: https://hasura.io/docs/latest/graphql/core/actions/action-handlers.html#http-handler
We have installed Apache Ranger and the Web UI works fine, most of the REST API method works fine on both PublicAPIsv2 and RoleREST as per https://ranger.apache.org/apidocs/ui/index.html.
I can get “test_role” id by calling GET /public/v2/api/roles/name/test_role which returns the id 409.
I can get test_role content by calling GET /public/v2/api/roles/409
I can change test_role users list by editing the response I get from GET /public/v2/api/roles/409 and submitting it through PUT /public/v2/api/roles/409
The body is:
{
"id": 409,
"isEnabled": true,
"createdBy": "admin",
"updatedBy": "admin",
"createTime": 1598241102841,
"updateTime": 1601975068428,
"name": "test_role",
"options": {},
"users": [
{
"name": "test_user1”,
"isAdmin": true
},
{
"name": “test_user2”,
"isAdmin": true
},
{
"name": “test_user3”,
"isAdmin": false
}
],
"groups": [
{
"name": "test_group”,
"isAdmin": false
}
],
"roles": []
}
But calling PUT /public/v2/api/roles/409/addUsersAndGroups returns “404 not found”.
I tried with the same body as above as parameter, and also with:
{
"users": [
{
"name": “test_user4”,
"isAdmin": true
}
]
}
Would anybody know what is the correct body to send as parameter to:
/public/v2/api/roles/409/addUsersAndGroups?
Also, making a wrong call such as GET /public/v2/api/roles/409/addUsersAndGroups returns “405 method not allowed”. So I believe it shows the end point does exist. I’m not sure why calling PUT public/v2/api/roles/409/addUsersAndGroups with (probably) incorrect body returns “404 not found” and not an error message related to the wrong parameter.
It happens because Apache Ranger API documentation is wrong, remove the suffix /addUsersAndGroups of your endpoint and it will work.
Example: https://ranger_url/service/roles/roles/409
Where 409 is the role ID, as you're using on your example.
The body that is needed:
{
"name": "test_role",
"users": [
{
"name": "test_user1",
"isAdmin": true
}
]
}
I'm currently building an application that requires me to retrieve users from the Graph API depending of a custom property, in that case, extoe82ql2v_test/companyName but so far, the API responded with Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'."
The request to retrieve the extension :
https://graph.microsoft.com/v1.0/schemaExtensions?$filter=id eq 'extoe82ql2v_test'
The result :
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions",
"value": [
{
"id": "extoe82ql2v_test",
"description": "Extend data for users",
"targetTypes": [
"User"
],
"status": "InDevelopment",
"owner": "d9a847ce-ca03-4779-88d6-c7e4f98297fe",
"properties": [
{
"name": "companyName",
"type": "String"
},
{
"name": "managerMail",
"type": "String"
},
{
"name": "arrivalDate",
"type": "DateTime"
},
{
"name": "expiryDate",
"type": "DateTime"
}
]
}
]
}
The request to retrieve the users depending of extoe82ql2v_test/companyName :
https://graph.microsoft.com/v1.0/users?$select=extoe82ql2v_test,givenName,surname,mail,mobilePhone,department,companyName,accountEnabled&$filter=extoe82ql2v_test/companyName eq 'test'
The result :
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'.",
"innerError": {
"date": "2020-07-24T20:46:51",
"request-id": "639b8131-70dd-4436-b624-88167fe105eb"
}
}
}
The same query with the Microsoft Graph .NET SDK :
var res = await _graphClient.Users.Request()
.Select($"extoe82ql2v_test,givenName,surname,mail,mobilePhone,department,companyName,accountEnabled")
.Filter($"extoe82ql2v_test/companyName eq 'test'").GetAsync()
I don't understand what the issue is as I followed what the official documentation said about filtering custom properties
Any help is greatly appreciated
Edit : Here is how $select without a $filter looks like
Request :
https://graph.microsoft.com/v1.0/users?$select=givenName,surname,mail,mobilePhone,department,companyName,accountEnabled,extoe82ql2v_test
Response :
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(givenName,surname,mail,mobilePhone,department,companyName,accountEnabled,extoe82ql2v_test)",
"value": [
{
"givenName": "Antoine",
"surname": "D",
"mail": "antoine.d#contoso.com",
"mobilePhone": null,
"department": null,
"companyName": null,
"accountEnabled": true,
"extoe82ql2v_test": {
"#odata.type": "#microsoft.graph.ComplexExtensionValue",
"expiryDate": "2020-12-31T00:00:00Z",
"arrivalDate": "2020-07-22T00:00:00Z",
"managerMail": "antoine.d#contoso.com",
"companyName": "test"
}
}
]
}
Edit 2:
I successfully filtered the users with another custom attributes, extoe82ql2v_test/managerMail, it's progress but I still need to apply a filter on extoe82ql2v_test/companyName and make it works
Edit 3:
Filtering on extoe82ql2v_test/expiryDate and extoe82ql2v_test/arrivalDate also works, both of these attributes are useless to filter but at least I know they work. As for extoe82ql2v_test/companyName, I wonder if it is because this attribute exists in both the schema extensions and the User Graph object ?
I just faced the same problem and made it work by adding "$count=true" in the query parameters.
I also noticed it seems to need ConsistencyLevel=eventual in the request header.
For example:
https://graph.microsoft.com/v1.0/users?$filter=CompanyName eq 'xxxx'&$select=id,displayName,CompanyName
Bad Request - 400 - 146ms
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'.",
...
}
https://graph.microsoft.com/v1.0/users?$count=true&$filter=CompanyName eq 'xxxx'&$select=id,displayName,CompanyName (with header ConsistencyLevel=eventual)
OK - 200 - 404ms
\o/
(I got the hint by looking at this question Microsoft Graph API cannot filter /users by companyName?)
SPEC provides next example how to identify schema:
{
"$id": "http://example.com/root.json",
"definitions": {
"B": {
"$id": "other.json",
},
}
}
#/definitions/B
http://example.com/other.json
http://example.com/other.json#
http://example.com/root.json#/definitions/B
But how is it identified if root schema root.json would be defined under /some/path instead of / path?
{
"$id": "http://example.com/some/path/root.json",
"definitions": {
"B": {
"$id": "other.json",
},
}
}
How other.json should be identified?
http://example.com/other.json
or:
http://example.com/some/path/other.json
And which part of SPEC defines this?
Schemas can be identified by any URI that has been given to them,
including a JSON Pointer or their URI given directly by "$id". In all
cases, dereferencing a "$ref" reference involves first resolving its
value as a URI reference against the current base URI per RFC 3986
[RFC3986].
(Dereferencing section)[http://json-schema.org/latest/json-schema-core.html#rfc.section.8.3.2] of the spec.
The "base URI" is defined in RFC 3986 which is referenced in the JSON Schema specification.
It's not super easy to understand because it's quite complex. In the case of a URL, where the reference to resolve is is a non hash fragment, the base URI is is the URI parts before (but including) the last slash.
(Note: JSON Schema defines that the value of an $id must be an absolute URI, without any fragments.)
So to answer your question specifically other.json should be identified as http://example.com/some/path/other.json.
You can see this in action if you try using the following schema in this online JSON Schema validator...
{
"$id": "http://example.com/blah/root.json",
"definitions": {
"A": {
"$id": "#foo"
},
"B": {
"$id": "other.json",
"definitions": {
"X": {
"$id": "#bar"
},
"Y": {
"$id": "t/inner.json"
}
}
},
"C": {
"$ref": "http://example.com/blah/other.json"
}
},
"properties":{
"a": { "$ref": "#/definitions/C" }
}
}
In the $ref for "C", if you remove /blah, the validator will complain it can no longer resolve the reference.
I am using an API call which returns a JSON response. I want to access the data inside the response so I can create some nice display cards showing the info and pictures. Here is a snippet from the response, the response property is populated with about 20 objects I'll include just two for brevity:
{
"success": true,
"message": "",
"result": [
{
"MarketCurrency": "LTC",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Litecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-LTC",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/R29q3dD.png"
},
{
"MarketCurrency": "DOGE",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Dogecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-DOGE",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/e1RS4Hn.png"
},
In my Rails controller I'm using JSON.parse and I'm trying to turn it into an object with the Open struct option:
#markets = JSON.parse(markets.to_json, object_class: OpenStruct)
In my view I'll do this <%=#markets.class%> and it shows Array and not object. So I try this <%=#markets.size%> and it shows 1. If I do <%=#markets[0]['success']%> I would expect it to return true but it returns 'success'. So, I'm not understanding why the ostruct library isn't working like I would expect or how I can get to the objects stored in the result array. Any help is greatly appreciated!
You already have a JSON response, isn't needed to use to_json again, try just parsing that object, and then use the dot . to access its fields, as an OpenStruct object now then you can access them as methods:
require 'json'
a = '{
"success": true,
"message": "",
"result": [{
"MarketCurrency": "LTC",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Litecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-LTC",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/R29q3dD.png"
}, {
"MarketCurrency": "DOGE",
"BaseCurrency": "BTC",
"MarketCurrencyLong": "Dogecoin",
"BaseCurrencyLong": "Bitcoin",
"MinTradeSize": 1e-8,
"MarketName": "BTC-DOGE",
"IsActive": true,
"Created": "2014-02-13T00:00:00",
"Notice": null,
"IsSponsored": null,
"LogoUrl": "https://i.imgur.com/e1RS4Hn.png"
}]
}'
b = JSON.parse(a, object_class: OpenStruct)
p b.success
# => true
After much debugging and some assistance, I was able to get it to work. The response from the API call was an array with one item. The item was a long string of the entire dataset.
In order to get the expected behavior of "true" when calling #markets.success, I first had to
raw_markets = JSON.parse(markets.to_json)
followed by
#markets = raw_markets.map do |market|
JSON.parse(market, object_class: OpenStruct)
Note: the variable markets holds the original api call:
markets = open('url-to-api')
After this I would get #markets.success = "true" and #markets.result[0] held the first result, #markets.result[1] held the second result, and so on.