Is there a way to name graphql requests in the devtool network tab? - graphql

I'm using apollo as my client and I run plenty of queries and mutations on my app. I was wondering if there is a way to have each of my query/mutation displayed by its name (eg. getProduct) instead of all showing as "graph" in my network tab? I'm on Brave (Chromium).
It would make debugging easier if I didn't have to click on each one and check the headers or the response to identify which query or mutation this request corresponds to.
Here's how it currently shows in my devtools:
network tab screenshot
Thanks a lot!

Maybe there is a better way but here the minimal code I could do to make it.
import {
ApolloClient,
ApolloLink,
HttpLink,
InMemoryCache,
} from '#apollo/client';
const httpLink = new HttpLink({ uri: MY_BASE_URL });
const namedLink = new ApolloLink((operation, forward) => {
operation.setContext(() => ({
uri: `${MY_BASE_URL}?${operation.operationName}`,
})
);
return forward ? forward(operation) : null;
});
export const client = new ApolloClient({
link: ApolloLink.from([namedLink, httpLink]),
cache: new InMemoryCache(),
});
You'll have to name your query :
import { gql } from "#apollo/client";
const QUERY = gql`
query QueryName {
...
}
`;
Hope it'll help.

uri prop of HttpLink can accept function which have operation as an arg
so it can be done like this as well:
const httpLink = new HttpLink({ uri: (operation) => `${MY_BASE_URL}?${operation.operationName}` });

Related

How to pass different Apollo client to useMutation graphql

I am new to graphql and react. Currently one apollo client is used by default for all useQuery and useMutation which was intialized via ApolloProvider.
Now I have to pass different apollo clients (having different uri) to different queries and mutations. I am able to pass different clients in useQuery() but not able to do the same in useMutation().
// Client initialized via ApolloProvider
const client = new ApolloClient({
cache: new InMemoryCache(),
link: httpLink1,
});
// Custom client with different http link
const customClient = new ApolloClient({
cache: new InMemoryCache(),
link: httpLink2,
});
// This is working where I can see it is using httpLink2
const { loading, error, data } = useQuery(GET_ITEMS, {
client: customClient
});
const [myMutation] = useMutation(LOAD_ITEMS)
const loadItem (): void => {
// not working. By default, the apollo client instance that's passed down via context is use.
const variables = { item: 1, client: customClient }
myMutation({ variables })
// rest of the code
}
As per below useMutation() documentation I can see that we can pass different clients.
https://www.apollographql.com/docs/react/data/mutations/#client. But somehow it is not working for me.
Could someone please help me here.
Thanks in advance.
You can use the same apollo client but use the httpLink conditionally.
https://www.apollographql.com/docs/react/api/link/introduction#providing-to-apollo-client
Creating the link:
import { ApolloLink, HttpLink } from '#apollo/client';
const directionalLink = ApolloLink.split(
operation => operation.getContext().clientName === "second",
new HttpLink({ uri: "http://localhost:4000/v1/graphql" }),
new HttpLink({ uri: "http://localhost:4000/v2/graphql" })
),
Initializing apollo client:
const client = new ApolloClient({
cache: new InMemoryCache(),
link: directionalLink
});
In the component:
const {data, error, loading} = useQuery(GET_STUFF, {
context: { version: "second" }
});

Apollo readQuery, get data from cache

I'm trying to get data from Apollo cache. I know that data is there because in Apollo dev tools specified records are available.
In my react app I making a simple click and set Id which later passes to the query. Result from client.readQuery(...) is null. I'm spinning around because don't know why. I'm using code exactly the same way as in docs.
Here's a QUERY:
export const RECRUIT_QUERY = gql`
query Recruit($id: ID!) {
Recruit(_id: $id) {
_id
firstName
}
}
`;
Usage of apollo hooks in component:
const client = useApolloClient();
const recruit = client.readQuery({
query: RECRUIT_QUERY,
variables: { id: selectedId }
})
Configuration of apollo:
export const client = new ApolloClient({
link: concat(
authMiddleware,
new HttpLink({
uri: process.env.REACT_APP_API_URL,
}),
),
cache: new InMemoryCache(),
});
Here's apollo store preview:
Using readFragment covers my expectation. previously I have tried this solution but wrongly, ex:
client.readFragment({
id: '4587d3c2-b3e7-4ade-8736-709dc69ad31b',
fragment: RECRUIT_FRAGMENT,
});
In fact Appollo store cound't find this record. Correct solution looks like this:
client.readFragment({
id: 'Recruit:4587d3c2-b3e7-4ade-8736-709dc69ad31b',
fragment: RECRUIT_FRAGMENT,
})

Apollo-client State management cache is not updating automatically after save and delete operation

I am using apollo-client for graphql calls along with I added state management with in the package apollo-client. In graphql module, assigned InMemoryCache to cache variable and client variable is exported.Client variable is imported in component so data is available in client.cache.data after default get call executed but I want to update client cache after save and delete graphql operations success callbacks
Here is my graphql.module.ts:
import {NgModule} from '#angular/core';
import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular';
import { ApolloClient } from 'apollo-client';
import {InMemoryCache} from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
const cache = new InMemoryCache();
const link = new HttpLink({
uri:'https://api.graph.cool/simple/v1/ciyz901en4j590185wkmexyex'
});
export var client = new ApolloClient({
cache,
link
});
#NgModule({
})
and my service call implementation
client
.query({
query: gql`
{
fORoomTypes()
{
nodes
{
roomTypeId
roomType
ratSingle
ratDouble
ratExtra
statu
}
}
}
`,
})
.then(result => {
callback(result);
});
after callback client.cache.data contain data, I want to call this data with cache queries and I want to update cache automatically
this is my save service implementation
const post = gql`
mutation
{
saveRtype(rt:
{
rty:
{
rt:"Club room"
rat:4000
cchub:4500
ext:800
statu:1
}
traCheck:1
}
)
}
`
client.mutate({
mutation: post
}).then((data) => {
callback(data)
});
I've only used apollo client with React but hopefully can shed light on how it works. For this to happen "automatically", you either need to call refetchQueries to refetch fORoomTypes after the mutation, or manually update the cache. I noticed your responses do not return an id property, so how would it know which one to update? If there is an identifier that isn't called "id", then register it following this documentation.
Here is the link to documentation in general for what you want
https://www.apollographql.com/docs/angular/features/cache-updates/

How do you make Schema Stitching in Apollo Server faster?

Initially, I tried to use a Serverless Lambda function to handle schema stitching for my APIs, but I started to move toward an Elastic Beanstalk server to keep from needing to fetch the initial schema on each request.
Even so, the request to my main API server is taking probably ten times as long to get the result from one of the child API servers as my child servers do. I'm not sure what is making the request so long, but it seems like there is something blocking the request from resolving quickly.
This is my code for the parent API:
import * as express from 'express';
import { introspectSchema, makeRemoteExecutableSchema, mergeSchemas } from 'graphql-tools';
import { ApolloServer } from 'apollo-server-express';
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
async function run () {
const createRemoteSchema = async (uri: string) => {
const link = new HttpLink({ uri, fetch });
const schema = await introspectSchema(link);
return makeRemoteExecutableSchema({
schema,
link
});
};
const remoteSchema = await createRemoteSchema(process.env.REMOTE_URL);
const schema = mergeSchemas({
schemas: [remoteSchema]
});
const app = express();
const server = new ApolloServer({
schema,
tracing: true,
cacheControl: true,
engine: false
});
server.applyMiddleware({ app });
app.listen({ port: 3006 });
};
run();
Any idea why it is so slow?
UPDATE:
For anyone trying to stitch together schemas on a local environment, I got a significant speed boost by fetching 127.0.0.1 directly instead of going through localhost.
http://localhost:3002/graphql > http://127.0.0.1:3002/graphql
This turned out not to be an Apollo issue at all for me.
I'd recommend using Apollo engine to observe what is really going on with each request as you can see on the next screenshot:
you can add it to your Apollo Server configuration
engine: {
apiKey: "service:xxxxxx-xxxx:XXXXXXXXXXX"
},
Also, I've experienced better performance when defining the defaultMaxAge on the cache controle:
cacheControl: {
defaultMaxAge: 300, // 5 min
calculateHttpHeaders: true,
stripFormattedExtensions: false
},
the other thing that can help is to add longer max cache age on stitched objects if it does make sense, you can do this by adding cache hints in the schema stitching resolver:
mergeSchemas({
schemas: [avatarSchema, mediaSchema, linkSchemaDefs],
resolvers: [
{
AvatarFlatFields: {
faceImage: {
fragment: 'fragment AvatarFlatFieldsFragment on AvatarFlatFields { faceImageId }',
resolve(parent, args, context, info) {
info.cacheControl.setCacheHint({maxAge: 3600});
return info.mergeInfo.delegateToSchema({
schema: mediaSchema,
operation: 'query',
fieldName: 'getMedia',
args: {
mediaId: parseInt(parent.faceImageId),
},
context,
info,
});
}
},
}
},
Finally, Using dataLoaders can make process requests much faster when enabling batch processing and dataloaders caching read more at their github and the code will be something like this:
public avatarLoader = (context): DataLoader<any, any> => {
return new DataLoader(ids => this.getUsersAvatars(dataLoadersContext(context), ids)
.then(results => new Validation().validateDataLoaderArrayResults(ids, results))
, {batch: true, cache: true});
};

How to make query in Apollo-Client?

Using REST-API, we can make fetch query than make query to server.
I use "Apollo-client", but I want to create query witout connecting this query to component. Can I do it?
May be I should use methods client.query (http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient.query) and client.mutate or something like this?
const apolloClient = new ApolloClient({
networkInterface: createNetworkInterface({uri: 'http://localhost:3003/graphql'})
});;
const loginQueruy = gql `Your query code here`,
and then in code
const apolloQuery = {
query: loginQuery,
};
apolloClient
.query(apolloQuery)
.then((res) => {
console.log("RES", res)
})

Resources