How to format NewRelic NerdGraph API calls from java/groovy client? - graphql

I'm trying to extract some metric data from NewRelic using NerdGraph API. It works perfectly while using curl, but I'm having problems with calling it from groovy/java client.
NerdGraph API request is as follows:
{
actor {
entitySearch(query: "name like 'my-service-name'") {
results {
entities {
tags {
key
values
}
guid
}
}
}
}
}
The following curl call works fine:
curl --location --request POST 'https://api.newrelic.com/graphql' --header 'API-Key: MY-API-KEY' --header 'Content-Type: application/json' --data-raw '{"query":"{\n actor {\n entitySearch(query: \"name like '\''my-service-name'\''\") {\n results {\n entities {\n tags {\n key\n values\n }\n guid\n }\n }\n }\n }\n}"}'
In my groovy code I'm trying to instantiate request like this:
String request = '''
{ "query": "{
actor {
entitySearch(query: "name like 'my-service-name'") {
results {
entities {
tags {
key
values
}
guid
}
}
}
}
}"
}
'''
..or this:
String request = '{"query":"{\n actor {\n entitySearch(query: \"name like \'my-service-name\'\") {\n results {\n entities {\n tags {\n key\n values\n }\n guid\n }\n }\n }\n }\n}"}'
Neither works. I'm getting https://api.newrelic.com/graphql -> 400 : Bad Request
How should I escape special characters (quote and double quote) to make it work?

I had a similar problem in C# and came to this question looking for answers. Hopefully you've found a solution, but for me the key was sending the data as a byte[] as opposed to a string...
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.newrelic.com/graphql"))
{
string payload = #"{actor {account(id: NEWRELICACCOUNTID) {nrql(query: ""SELECT rate(count(*), 1 hour) AS 'RequestsPerHour' FROM Transaction TIMESERIES 1 hour FACET `Channel` EXTRAPOLATE SINCE 1 weeks ago"") {results}}}}";
request.Headers.TryAddWithoutValidation("API-Key", "MYAPIKEY");
request.Content = new ByteArrayContent(encoding.GetBytes(payload));
var response = await httpClient.SendAsync(request);
}
}
Hope this helps you or someone else!

Related

Golang gRPC proto unexpected token

I defined a proto in Golang shown below (and the corresponding API path) and am trying to test the POST API call as shown below, but am getting the following unexpected token error.
I verified that this error is from the award_map section (defined to be map<string, People>), in which People is an array of strings. What is the proper data format for award_map in the curl request? Thanks
Error:
{"code":3, "message":"proto: syntax error : unexpected token [","details":[]}
Post API request:
curl --header "Content-Type: application/json" \
-- request POST \
-- data '{"school_name":"MIT", "awards":["Summa-cum-laude", "Magna-cum-laude"], "award_map":{"Summa-cum-laude":[], "Magna-cum-laude": ["john", "mark"]}}' \
<POST_ENDPOINT>
Proto definitions:
message People {
repeated string names = 1;
}
message School {
string school_name = 1;
repeated string awards = 2;
map<string, People> award_map = 3;
}
The award_map values need to be full People messages, not just arrays of strings. Try this:
{
"school_name":"MIT",
"awards": [
"Summa-cum-laude",
"Magna-cum-laude"
],
"award_map": {
"Summa-cum-laude": {
"names": []
},
"Magna-cum-laude": {
"names": [
"john",
"mark"
]
}
}
}
Copy/paste version:
'{"school_name":"MIT","awards":["Summa-cum-laude","Magna-cum-laude"],"award_map":{"Summa-cum-laude":{"names":[]},"Magna-cum-laude":{"names":["john","mark"]}}}'
Note that it isn't possible to define something like map<string, repeated string>.

How to get the current earnings of the farms via Elrond REST API

How I could obtain the current earnings of a farm from Maiar Exchange via Elrond REST API?
For example, for the LKMEX farm I want to determine the current earnings (My Earned MEX) in MEX and/or USDT since the latest harverst or 'reinvest'. Thanks!
Based on what I was looking in maiar.exchange. You can determine there is a graphql request for this.
You can do graphql request to https://graph.maiar.exchange/graphql. I did not search if there is any OpenAPI spec to know if there is any security bound to this route. However, to help you out, here is the graphql (with redacted content), that is used to get current amount in farm with current harvestable amount:
{
"variables": {
"getRewardsForPositionArgs": {
"farmsPositions": [
{
"attributes": "XXXX",
"identifier": "MEXFARM-XXXXX-XXXXX",
"farmAddress": "erd1XXXX",
"liquidity": "19700000000000000000000000"
},
{
"attributes": "XXX",
"identifier": "LKFARM-XXXXXXX-XXXXXX",
"farmAddress": "erd1XXXXX",
"liquidity": "19700000000000000000000000"
},
]
}
},
"query": "query ($getRewardsForPositionArgs: BatchFarmRewardsComputeArgs!) {\n getRewardsForPosition(farmsPositions: $getRewardsForPositionArgs) {\n rewards\n remainingFarmingEpochs\n decodedAttributes {\n aprMultiplier\n compoundedReward\n initialFarmingAmount\n currentFarmAmount\n lockedRewards\n identifier\n __typename\n }\n __typename\n }\n}\n"
}
Liquidity is from where you want to get the data. There might be a need to do another graphql request before doing this to know where you are for liquidity.

Can't solve Playground error: Variable \"$input\" of required type \"MemberInput!\" was not provided

I've beat on this issue for what seems like a week and nothing online solves it. No data object is returned, not even "null". I'm converting from a working REST CRUD app to GraphQL. Not as easy as I expected.
My mutation in Playground:
mutation createMember($input: MemberInput!) {
createMember (input: $input) {
first_name
last_name
user_name
}
}
Playground Query Variables below: (Not in the headers section.)
{
"input": {
"first_name": "John",
"last_name": "Creston",
"user_name": "jc"
}
}
The schema: (The queries work fine and the Member type, an entity in TypeORM, works with them and full REST CRUD.)
input MemberInput {
first_name: String!
last_name: String!
user_name: String!
}
type Mutation {
createMember(input: MemberInput!): Member!
}
type Query {
getMembers: [Member]
getMember(member_id: Int!): Member!
checkUserName(user_name: String): Member
checkEmail(email: String): Member
}
I don't see how the resolver could be the problem for this error message but I'll add the Nestjs resolver:
#Mutation('createMember')
async createMember(#Args('input') input: MemberInput): Promise<Members> {
console.log('input in resolver: ', input);
return await this.membersService.addItem(input);
}
The service works with REST and the queries so that should be a problem. The console.log in the resolver never appears in terminal.
From the Copy CURL button:
curl 'http://localhost:3000/graphql' -H 'Accept-Encoding: gzip,
deflate, br' -H 'Content-Type: application/json' -H 'Accept:
application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin:
http://localhost:3000' --data-binary '{"query":"mutation
createMember($input: MemberInput!) {\n createMember (input: $input)
{\n first_name\n middle_initial\n last_name\n
user_name\n pitch\n main_skill_title\n \tskill_id_array\n
skills_comments\n other_skills\n links\n country\n
email\n member_status\n }\n}"}' --compressed
I had same problem, in variables i had comma at the end of last parameter. gql gave me same error.
change this:
{
"input": {
"param1": "val1",
"param2": "val2",
}
}
to this:
{
"input": {
"param1": "val1",
"param2": "val2" // no comma here
}
}
A bit complicated to explain but we've probably all be there. I was trying different "solutions" and the remains of one was accidentally left in my JSON data object. The full object has more properties than my brief one above. An array shouldn't be "[]" in JSON. I was getting tired and desperate last night. I changed the resolver to what I posted above but it didn't fix the problem because of the experiment in JSON caused the same error as before. So I was looking in the wrong places. Once I noticed and removed the quotes my full object's data was posted to the Postgres db.
The code above works.
It would be nice if there were more specific GraphQL errors. I suspected that this one is very general but that didn't help. It didn't indicate that the original problem was in the resolver and later that I had a data input error.
In my case, my code is implementing this plugin graphql-query-complexity for which there is a known bug: https://github.com/slicknode/graphql-query-complexity/issues/69.
Wrapping the plugin in a try/catch I am able to skip the error validation.

GraphQL fragment JSON format

I'm attempting to read some data out of GitHub with their v4 (GraphQL) API. I've written a Java client that is working fine up until I start replacing some of the query with GraphQL fragments.
I was using GraphiQL to initially test my queries, and adding fragments was pretty simple in there. However, when translating to JSON, I haven't figured out the correct format. I've tried:
{ "query": "{ ... body_of_query ... } fragment fragname on Blob { byteSize text }" }
{ "query": "{ ... body_of_query ... }, fragment fragname on Blob { byteSize text }" }
{ "query": "{ ... body_of_query ... }", "fragment": "{fragname on Blob { byteSize text } }" }
EDIT: Adding for #Scriptonomy:
{
query {
search(first:3, type: REPOSITORY, query: \"language:HCL\") {
edges {
node {
... on Repository {
name
descriptionHTML
object(expression: \"master:\") {
... on Tree {
...recurseTree
}
}
}
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
fragment recurseTree on Tree {
entries {
name
type
}
}
I'm sure it would be fun and all to keep throwing random variations on this, and my morning has been huge fun searching various GraphQL docs and blogs on fragments, and I may have even actually guessed the correct answer but had mismatched parens (I'm just using hardcoded JSON until I know the format -- perhaps not the wisest choice looking back on it).
I'm hoping that someone may know the correct format and set me on the correct course before I keel over from GraphQL-doc over-exposure.
Fragments are sent in the same property of the JSON body as the query itself. You can see an example for using fragments here.
A valid GraphQL request is usually either a GET request that encodes the query as URL query parameter, or a POST request with a JSON body. The JSON body has one required key, query and one optional field, variables. In your case, the JSON needs to look like this:
{
"query": "{\n query {\n search(first:3, type: REPOSITORY, query: \"language:HCL\") {\n edges {\n node {\n ... on Repository {\n name\n descriptionHTML\n object(expression: \"master:\") {\n ... on Tree {\n ...recurseTree\n }\n }\n }\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment recurseTree on Tree {\n entries {\n name\n type\n }\n}"
}
That is the JSON.stringify version of the verbatim query string in your question.
I recommend you to run queries from a GraphiQL instance connected to your GitHub GraphQL API and look into the network request. You can copy the GraphQL request as cuRL to see how the JSON body needs to look like.
If you still obtain a 400, please share some code, because that means your request was malformed, so it probably never hit the GraphQL parser in the first place.
There is no need to translate GraphQL Query to JSON. This would be your query:
"{ query { ... body_of_query ... } fragment fragname on Blob { byteSize text } }"
For future users, and people like me who stumbled upon this hurdle.
Query needs to be sent in the given order;
{ "query": "fragment fragname on Blob { byteSize text } methodName(ifMethodParam: paramVal){...fragname }" }
Hope this will help others.

Issue while including enum type in unions within avro schema

I am working with Apache Kafka to send messages to Kafka topics. I am trying to use unions in Avro Schemas including enum types for message validation. But I am facing an issue with the usage of enum types within union. I am using Kafka REST API through POSTMAN tool to post a record/message to a topic with schema validation. Below is the request payload including schema and records inline -
{
"key_schema": "{\"type\": \"record\", \"name\": \"key\", \"fields\": [{\"name\": \"keyInput\", \"type\": \"string\"}]}",
"value_schema": "{\"type\": \"record\", \"name\": \"value\", \"fields\": [{\"name\": \"valueInput1\", \"type\": \"string\"},{\"name\": \"valueInput2\",\"type\":[{\"type\":\"enum\",\"name\":\"actorobjType\",\"symbols\":[\"Agent\",\"Group\"]},\"null\"],\"default\":null}]}",
"records": [
{
"key": {
"keyInput": "testUser-key"
},
"value": {
"valueInput1": "testUser-value",
"valueInput2": "Agent"
}
}
]
}
I am getting the following error when I am trying to insert a record using above request payload -
{
"error_code": 42203,
"message": "Conversion of JSON to Avro failed: Failed to convert JSON to Avro: Expected start-union. Got VALUE_STRING"
}
After searching in different sites including stackoverflow, I came through a suggestion
asking to explicitly specify the type while passing the record as below -
{
"key_schema": "{\"type\": \"record\", \"name\": \"key\", \"fields\": [{\"name\": \"keyInput\", \"type\": \"string\"}]}",
"value_schema": "{\"type\": \"record\", \"name\": \"value\", \"fields\": [{\"name\": \"valueInput1\", \"type\": \"string\"},{\"name\": \"valueInput2\",\"type\":[{\"type\":\"enum\",\"name\":\"actorobjType\",\"symbols\":[\"Agent\",\"Group\"]},\"null\"],\"default\":null}]}",
"records": [
{
"key": {
"keyInput": "testUser-key"
},
"value": {
"valueInput1": "testUser-value",
"valueInput2": {
"enum": "Agent"
}
}
}
]
}
But then I face the below error -
{
"error_code": 42203,
"message": "Conversion of JSON to Avro failed: Failed to convert JSON to Avro: Unknown union branch enum"
}
The same suggestion worked fine for unions with other types like string and map, but with unions including enum, that does not seem to work.
I also thought there may be some other type which needs to be used for enum specification, Hence I tried some other words like below -
"valueInput2": {
"string": "Agent"
}
and
"valueInput2": {
"enumeration": "Agent"
}
But none of them seem to work. Please help me resolve this.
I ended up here, and davis michael's answer gave a hint, which helped me eventually figure it out.
Within the context of the question,
"valueInput2": {
"actorobjType": "Agent"
}
As ENUM type is not exist in JSON format, value type should be changed to correct one:
namespace + type name
In your case, it will be namespace + actorobjtype : "agent"

Resources