How to get subscription data from client cache? - apollo

i'm new to all the hot graphql/apollo stuff.
I have a subscription which gets a search result:
export const SEARCH_RESULTS_SUBSCRIPTION = gql`
subscription onSearchResultsRetrieved($sid: String!) {
searchResultsRetrieved(sid: $sid) {
status
clusteredOffers {
id
}
}
}
`;
Is it possible to query the "status" field from client cache if i need it inside another component? Or do i have to use an additional ?
In the apollo dev-tools i can see that there is a cache entry under "ROOT_SUBSCRIPTION" not "ROOT_QUERY". What does that mean?
....thanks

I found out that subscribeToMore is my friend to solve this.
At first i wrote a normal query for the data i want to subscribe to have cached data, then the cache will be updated by the subscription.
<3 apollo

Related

Postman send multiple requests

I've got a PATCH request that looks like this:
{{host}}/api/invoice/12345678/withdraw
host is a variable determining the environment.
For this request I need to add a unique authorization token.
The problem is I need to send dozens of such requests. Two things change for each request:
id of invoice (for this case is '12345678')
auth token (herebetoken1).
How can I automate it?
You can use Postman Runner for your problem. In Runner, you can send specified requests in specified iterations and delay with data (json or csv file).
For more info, I suggest you take a look at the links below.
Importing Data Files in Postman
Using CSV and JSON Data Files
Request:
Runner:
Data: (You can choose one of them)
Json Data: (data.json)
csv Data: (data.csv)
Preview Data in Runner:
Result:
use the below pre-request script , and call replace id in url and auth in authorization with {{id}} and {{token}} variables . Use collection runner to execute it .
Replace the hashmap with what you requires
hashmap = {
"1234": "authtoken1",
"2222": "authtoken2"
}
pm.variables.get("count") === undefined ? pm.variables.set("count", 0) : null
let keyval = Object.entries(hashmap)
let count = pm.variables.get("count")
if (count < keyval.length) {
pm.variables.set("id", keyval[pm.variables.get("count")][0])
pm.variables.set("token", keyval[pm.variables.get("count")][1])
pm.variables.set("count", ++count)
keyval.length===count? null:postman.setNextRequest(pm.info.requestName)
}
Example collection:
https://www.getpostman.com/collections/43deac65a6de60ac46b3 , click inport and import by link

What I should use instead of resolvers?

As u already know the Local resolvers are deprecated so we can't use it as a perspective way to handling REST cache. What we should use instead of resolvers?
'field policies' are not good for that at all. Let's imagine... You have two different client queries: getBooks and getBook. Each query getting data from the rest API. Somehow we need to handle the situation when we already got the data from getBooks and runing another query getBook. getBook should not make a request because the data were already cached. We did that in resolvers before it was deprecated. We were just checking the cache and return the data if it already exists in the cache if not did a request. How we can handle this in current circumstances?
Sorry but it's a bit not what I meant. Here is a code example:
export const getBooks = gql`
query getBooks () {
getBooks ()
#rest(
type: "Book"
path: "books"
endpoint: "v1"
) {
id
title
author
}
}
`
export const getBook = gql`
query getBook ($id: Int!) {
getBook (id: $id)
#rest(
type: "Book"
path: "book/{args.id}"
endpoint: "v1"
) {
id
title
author
}
}
`
So we have two different queries. The goal is when we run both in turn the getBook should not make a REST request because we already have the same data in the cache since we get it from getBooks. Before resolvers were deprecated we handle it in resolvers. Like: if this ID is not exist in the cache just make a request if exist give me data from the cache. How we can do that now?
As u can see fetchPolicy it's completely different.
Local fields it's also not good because it's something about fields not about the whole entity.

Pull all pull reviews in github api

I want to be able to pull all github pull reviews via the api. At the moment you can only GET a review via a specific number as per the below
GET /repos/:owner/:repo/pulls/:pull_number/reviews
Is there a way that instead of just 1 pull_number i can pull through all pull reviews?
Im using Postman for the requests.
You can use GraphQL API v4 iterating over the pull requests and getting reviews list for each one. But it would give you a bunch of issues that have no reviews, so you would need to use the Github Search API to filter only issues of type PR that have been reviewed :
https://api.github.com/search/issues?q=repo:mui-org/material-ui%20type:pr%20-review:none
Using GraphQL v4 you can get the reviews easily :
{
search(type: ISSUE, query: "repo:mui-org/material-ui type:pr -review:none", first: 100) {
issueCount
nodes {
... on PullRequest {
number
reviews(first: 100) {
nodes {
author {
login
}
bodyText
state
createdAt
}
}
}
}
}
}

How do I call another micro-service from my micro-service?

This might sound a little odd, but I'm facing a situation where I have a micro-service that assembles some pricing logic, but for that, it needs a bunch of information that another micro-service provides.
I believe I have two options: (1) grab all the data I need from the database and ignore the GraphQL work that was done in this other micro-service or (2) somehow hit this other micro-service from within my current service and get the data I need.
How would someone accomplish (2)?
I have no clear path of how to get that done without creating a mess.
I imagine that turning my pricing micro-service into a small client could work, but I'm just not sure if that's bad practice.
After much consideration and reading the answers I got here, I decided to turn my micro-service into a mini-client by using apollo-client.
In short, I have something like this:
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
// Instantiate required constructor fields
const cache = new InMemoryCache();
const link = new HttpLink({
uri: 'http://localhost:3000/graphql',
});
const client = new ApolloClient({
// Provide required constructor fields
cache: cache,
link: link,
});
export default client;
That HttpLink is the federated schema, so I can call it from my resolver or anywhere else like this:
const query = gql`
query {
something(uid: "${uid}") {
field1
field2
field3
anotherThing {
field1
field2
}
}
}
`;
const response = await dataSources.client.query({query});

How can I use Apollo/GraphQL to incrementally/progressively query a datasource?

I have a query like this in my React/Apollo application:
const APPLICATIONS_QUERY = gql`
{
applications {
id
applicationType {
name
}
customer {
id
isActive
name
shortName
displayTimezone
}
deployments {
id
created
user {
id
username
}
}
baseUrl
customerIdentifier
hostInformation
kibanaUrl
sentryIssues
sentryShortName
serviceClass
updown
updownToken
}
}
`;
The majority of the items in the query are in a database and so the query is quick. But a couple of the items, like sentryIssues and updown rely on external API calls, so they make the duration of the query very long.
I'd like to split the query into the database portion and the external API portion so I can show the applications table immediately and add loading spinners for the two columns that hit an external API... But I can't find a good example of incremental/progressive querying or merging the results of two queries with Apollo.
This is a good example of where the #defer directive would be helpful. You can indicate which fields you want to defer for a given query like this:
const APPLICATIONS_QUERY = gql`
{
applications {
id
applicationType {
name
}
customer #defer {
id
isActive
name
shortName
displayTimezone
}
}
}
`
In this case, the client will make one request but receive 2 responses -- the initial response with all the requested fields sans customer and a second "patch" response with just the customer field that's fired once that resolver is finished. The client does the heavy lifting and pieces these two responses together for you -- there's no additional code necessary.
Please be aware that only nullable fields can be deferred, since the initial value sent with the first response will always be null. As a bonus, react-apollo exposes a loadingState property that you can use to check the loading state for your deferred fields:
<Query query={APPLICATIONS_QUERY}>
{({ loading, error, data, loadingState }) => {
const customerComponent = loadingState.applications.customer
? <CustomerInfo customer={data.applications.customer} />
: <LoadingIndicator />
// ...
}}
</Query>
The only downside is this is an experimental feature, so at the moment you have to install the alpha preview version of both apollo-server and the client libraries to use it.
See the docs for full details.