What is query_hash in instagram? - graphql

I was working for the first time on graphql, and I saw that Instagram hash their queries.
I searched something, but I don't know if it is correct. The hash is like a persistedquery stored in a cache memory?
Or am I wrong?
Example: this is my request payload
{
"operationName":"user",
"variables":{},
"query":"query user {\n users {\n username\n createdAt\n _id\n }\n}\n"
}
this is instagram:
query_hash: 60b755363b5c230111347a7a4e242001
variables: %7B%22only_stories%22%3Atrue%7D
(it is in urlencode mode).
Now, how could I hash my query? I'm using NodeJS as backend and react js as frontend.
I would like to understand how it works x)! Thank you guys!

The persisted query is used to improve GraphQL network performance by reducing the request size.
Instead of sending a full query which could be very long, you send a hash to the GraphQL server which will retrieve the full query from the key-value store using the hash as the key.
The key value store can be memcached, redis, etc
The Apollo Server comes with automated persisted queries out of the box. I recommended gives it a try. They have publish a blog about it. https://blog.apollographql.com/automatic-persisted-queries-and-cdn-caching-with-apollo-server-2-0-bf42b3a313de
If you want to build your own solution, you can use this package to do the hashing yourself https://www.npmjs.com/package/hash.js

query_hash (or query_id) does not hash the variables or the parameters, it hashes the payload.
Lets say your actual path is /graphql and your payload is
{
"user": {
"profile": [
"username",
"user_id",
"profile_picture"
],
"feed": {
"posts": {
"data": [
"image_url"
],
"page_size": "{{variables.max_count}}"
}
}
}
}
Then this graphql payload will be hashed and it becomes d4d88dc1500312af6f937f7b804c68c3. Now instead of doing that on /graphql you do /graphql/query/?query_hash=d4d88dc1500312af6f937f7b804c68c3. This way you hashed the payload, as in you hashed the "keys" that are required from the graphql. So when you pass variables as a param then the payload does not actually change, because the variables are constant as well, and you are changing them on the backend, and not in the payload.

Related

Nested keys in redis using Spring Boot

I want to run a job in spring boot using quartz where multiple threads will execute the method.
What i want is to save the result in redis for every processing, so i can get idea how good job is working.
I want to save data in redis in this form.
{
"2020-04-20": [
{
"item_1": {
"success": "true",
"message": ""
}
},
{
"item_2": {
"success": "true",
"message": ""
}
}
]
}
I want to insert all the items in key date.
Since multiple threads are working , every thread is working on some item. So all item should be inserted into only key (date).
Is it possible?
one solution is to over-write the data of (date) key again and again , first getting data from redis, appending item on it and again saving the key in redis.
Is there another way , or using some annotation like #cacheable, #cacheput etc. so that i can create nested key. automatically item is appended in the (date) key.
Have you considered RedisJSON?
Soemthing like this (I haven't tested it, I don't have RedisJSON handy)
JSON.SET "2020-04-20" . [] // create the object once
JSON.ARRAPPEND "2020-04-20". '{ // every thread issues a command like this.
"item": {
"success": "true",
"message": "thread 123"
} }'
JSON.ARRAPPEND "2020-04-20". '{ // every thread issues a command like this.
"item": {
"success": "true",
"message": "thread 456"
} }'
JSON.ARRAPPEND are supposed to be atomic.
I solved it using redis set functionality.
I am using jedis client in my project.
It has very useful funtions like:-
1) sadd => insertion of element.O(1)
2) srem => deletion of element in set.O(1)
3) smembers => getting all results.O(N)
This is what i needed.
In my case date is the key, and other details (one object of json) is the member of the set. So, i convert my json to data to string when adding memeber in set, and when getting data i convert it back from string to json.
This solved my problem.
Note:- There is also list functionality that can be used. But time complexities for list are not O(1). In my case i am sure i will not have duplicates so set works for me.

How to camelCase my responses' fields and tables in Hausra or ApolloClient?

In my aplications I use Hasura for my graphql server and Apollo for the client. I have a postgres schema with snake_case table and field names, but I want to have camelCases keys in my responses' objects. Any known way to achieve that?
I can see that apollo server offers fieldResolver where it can be done(Convert snake_case to camelCase field names in apollo-server-express), but I found no similar option for Hasura/ApolloClient.
To make a long story short - currently, there is no such a solution for Hasura. The best suggestion I could get was to rename the column names manually, one-by-one via the console => DATA section => Modify tab:
you can expose any column with a different name in the GraphQLAPI without you having to rename the column itself...
you can do that in the hasura console as in the picture below
Any way to achieve that?
Check out GraphQL aliases.
https://graphql.org/learn/queries/#aliases
https://hasura.io/blog/customising-alias-graphql-fields-with-hasura/
Example:
# Query
query {
users {
id
name: full_name
email: email_addr
}
}
# Response
{
"data": {
"users": [
{
"id": "3ea1352a-6654-444d-9357-62816ccbd2b3",
"name": "Praveen",
"email": "email#mydomain.com"
}
]
}
}

How to prevent unnecessary G Suite API data consumption?

I am currently consuming data from the G Suite API.
An inconvenience I have found is that for some of the APIs the number of resources available might be quite large.
For instance, when I consume the Users:list API (https://www.googleapis.com/admin/directory/v1/users), given the number of resources and the maximum number of results per query I need to perform a significant number of queries. Find below an example JSON response:
{
"kind": "admin#directory#users",
"etag": "\"WqpSTs-zelqnIvn63V............................/v3ENarMfXkTh9ijs3OVkQRoUSVU\"",
"users": [
{
"kind": "admin#directory#user",
"id": "7720745322191632224007",
"etag": "\"WqpSTs-zelqnIvn63V........................PfcSmik3zEJwHAl1UbgSk\"",
"primaryEmail": ...,
...
},
{
"kind": "admin#directory#user",
"id": "227945583287518253104",
"etag": "\"WqpSTs-zelqnIvn63V..........-zY30eInIGOmLI\"",
"primaryEmail": ...,
...
},
...
N-users
...
]
}
I am running this query several times a day.
Ideally I would only retrieve the resources that have changed and the new ones, excluding from the response the ones that have not changed.
Is it possible to do that? If so, how?
Thank you in advance for your answers.
You could create custom attributes for your users, and then filter your requests using the query parameter according to your custom attribute.
Or define exactly what you mean by "changed" or "not changed" as the user properties will change on every login to update the last login attribute.
Update:
You can watch for changes on the list of users in your domain by supplying an address to receive notifications in a POST request to the watch endpoint:
https://www.googleapis.com/admin/directory/v1/users/watch
References:
Users.watch
Custom User Fields
Query string for User fields

In Relay.js, what is the `Client Mutation Identifier`?

In the relay documentation here, it says that:
Relay uses a common pattern for mutations, where there are root fields on the mutation type with a single argument, input, and where the input and output both contain a client mutation identifier used to reconcile requests and responses.
But in the example they provided, the input and output looked like this respectively:
// IntroducedShipInput
{
"input": {
"shipName": "B-Wing",
"factionId": "1"
}
}
// IntroducedShipPayload
{
"introduceShip": {
"ship": {
"id": "U2hpcDo5",
"name": "B-Wing"
},
"faction": {
"name": "Alliance to Restore the Republic"
}
}
}
So what is the client mutation identifier? And why, and how does it get used to reconcile requests and responses?
I'm still not 100% sure what exactly happened to the "client mutation identifier," but having done some research, it appears to have been a requirement in previous versions of Relay. This PR apparently removed the requirement by replacing it with some other mechanism, but it's not clear to me what that other mechanism does. I left a comment requesting more clarification around the documentation, which appears to be out of date.
At any rate, the client mutation identifier appears to have been related to some assumptions about mutation idempotency in Facebook's implementation of GraphQL.

ServiceNow REST API: return single column

Is there a way to perform a REST call to ServiceNow REST API that returns a single column of a table? I would like to query the server table for only the names of the servers and not have the entire record containing some 50 plus fields returned.
The latest REST Table API (as of Eureka, I think) supports the parameter sysparm_fields, which allows you to specify a comma-delimited list of fields to include in the response:
This URL template:
https://YOURINSTANCENAME.service-now.com/api/now/v1/table/incident?sysparm_fields=number,short_description,caller_id.name
Would give you a result with something like:
{
"result": [
{
"caller_id.name": "",
"short_description": "Unable to get to network file shares",
"number": "INC0000002"
}
]
}

Resources