Apollo dev tools not showing any data - apollo-client

The dev tools version is 4, same situation in Chrome as in Firefox.
"#apollo/client": "^3.5.7",
const createApolloClient = (authToken) => {
return new ApolloClient({
link: new HttpLink({
uri: "https://api2s.geomar.net.pl/v1/graphql",
headers: {
Authorization: `Bearer ${authToken}`,
},
}),
cache: new InMemoryCache(),
connectToDevTools: true, // should not be necessary but added just in case
defaultOptions: {
watchQuery: {
fetchPolicy: "cache-and-network",
pollInterval: 3000,
},
},
});
};
The application is React + Vitejs, if it makes any difference...
No idea where to start any debuging, please help...

Some other users reported a similar problem in the github project on this issue. I'm curious if this may be what's occurring on your end.

I could not make it work so I ended up using GraphQL Network Inspector Chrome extension
https://chrome.google.com/webstore/detail/graphql-network-inspector/ndlbedplllcgconngcnfmkadhokfaaln
No alternative for Firefox...

Related

Apollo Client - Simultaneous subscriptions from same component

I'm trying to make 2 simultaneous subscriptions with Apollo Client but the connection get closed and reopened every 2 seconds:
This is my code concerning subscriptions:
//apollo.js
const httpLink = createHttpLink({
includeUnusedVariables: true,
uri:
process.env.API_GRAPHQL ||
// Change to your graphql endpoint.
headers: {
Authorization:
"Bearer TOKEN",
},
});
const wsLink = new GraphQLWsLink(
createClient({
url: process.env.WS_GRAPHQL,
connectionParams: {
Authorization:
"Bearer TOKEN",
},
options: {
reconnect: true,
},
})
);
const link = split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription";
},
wsLink,
httpLink
);
// subscriber executer
const {
result: locationUpdates,
// loading: loadingLocation,
// error: devicesError,
// refetch: refetchDevices,
onResult: onResultLocations,
} = useSubscription(locationsLivesTrue, () => ({
}));
const { result: me, onResult: onResultMe } = useSubscription(
meUpdates,
() => ({})
);
If I execute only one subscription it works fine.
I also tried to subscribe directly from the client when I provide the app, but got the same result.
#juanmac My original post was deleted so I will answer here. Since you asked me a question there, I think it is fine I will answer inside your newest post ;)
A loop was used. Inside the loop, a subscribeToMore was used.
Inside that function, updateQuery was used.
There were some problems but I do not know if they were resolved. I will remind you, that it was React Native, and there are some stability issues with subscriptions etc.
I hope that helps.

Is it possible to define the HTTP headers for the GraphQL Playground that comes with Apollo Server?

I want to define some http headers for the GraphQL Playground, to be enabled by default and/or always. Essentially, I want to add:
"apollographql-client-name": "playground"
"apollographql-client-version": "yada-yada"
to be able to distinguish requests from the playground from any other requests on Apollo Studio. What's the best way?
By GraphQL Playground I refer to the one run by Apollo, the one documented here: https://www.apollographql.com/docs/apollo-server/testing/graphql-playground/
My current ApolloServer config looks something like this:
let apolloServerExpressConfig: ApolloServerExpressConfig = {
schema: schema,
playground: {
settings: {
"request.credentials": "include",
},
},
}
If I add tabs to it in an attempt to define the headers, like this:
let apolloServerExpressConfig: ApolloServerExpressConfig = {
schema: schema,
playground: {
settings: {
"request.credentials": "include",
},
tabs: [{
headers: {
"apollographql-client-name": "playground",
"apollographql-client-version": "yada-yada",
},
}],
},
}
the GraphQL playground no longer restores all tabs with their queries when reloading the page, which is very useful. I think there's some automatic tab management that gets removed as soon as you define tabs. I'm happy to have default headers defined for new tab creation, it's ok if those headers are exposed to the client.
My app already defines header, so, I can differentiate between the app and anything else that queries it, but I want to differentiate between my app, playground and anything else (the latter group should be empty).
Update:
https://github.com/apollographql/apollo-server/issues/1982#issuecomment-511765175
use the GraphQL Playground Express middleware directly [...] This would allow you to leverage the Express middleware req object, and set headers accordingly.
Here is a working example:
const app = require('express')()
const { ApolloServer, gql } = require('apollo-server-express')
// use this directly
const expressPlayground = require('graphql-playground-middleware-express').default
// just some boilerplate to make it runnable
const typeDefs = gql`type Book { title: String author: String } type Query { books: [Book] }`
const books = [{ title: 'Harry Potter and the Chamber of Secrets', author: 'J.K. Rowling' }, { title: 'Jurassic Park', author: 'Michael Crichton' }]
const resolvers = { Query: { books: () => books } }
const server = new ApolloServer({ typeDefs, resolvers });
//
// the key part {
//
const headers = JSON.stringify({
"apollographql-client-name" : "playground",
"apollographql-client-version": "yada-yada" ,
})
app.get('/graphql', expressPlayground({
endpoint: `/graphql?headers=${encodeURIComponent(headers)}`,
}))
server.applyMiddleware({ app })
//
// }
//
// just some boilerplate to make it runnable
app.listen({ port: 4000 }, () => console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`))
After page reload all tabs with their content are restored.
Answer to the original question:
It's not totally clear what you mean by Apollo Server GraphQL Playground. And what's your use case.
There is a desktop app, a web app, you can include GraphQL Playground as a module into your frontend, or as a middleware for your backend.
For the simplest case: switch to the "HTTP HEADERS" tab, add headers as JSON:
{
"apollographql-client-name": "playground",
"apollographql-client-version": "yada-yada",
}
For the case of frontend Playground you can pass tabs with headers property to <Playground/>:
<Playground
...
tabs={[{
name: 'Tab 1',
headers: {
"apollographql-client-name" : "playground",
"apollographql-client-version": "yada-yada" ,
}
...
}]}
/>,
For backend, you can use headers as well:
new ApolloServer({
...
playground: {
...
tabs: [{
...
headers: ...
}],
},
})
You can also
distinguish requests from the playground from requests from the actual apps
by going the opposite way: add extra headers to you actual apps.

nuxt.js + Apollo Client: How to disable cache?

I managed to get an nuxt.js + nest.js with typescript and apollo graphql running.
To test if graphql works, i used the files from this example, and added a Button to the nuxt.js-page (on:click -> load all cats via graphql).
Everything works, reading and writing.
The problem is that after doing a mutation via playground or restarting the nest.js server with other graphql-data, the nuxt.js-page is displaying the old data(on click). I have to reload the whole page in the browser, to get the Apollo-Client fetching the new data.
I've tried to add a 'no-cache'-flag and 'network-only'-flag to nuxt.config.ts without success:
apollo: {
defaultOptions: {
$query: {
loadingKey: 'loading',
fetchPolicy: 'no-cache'
}
},
clientConfigs: {
default: {
httpEndpoint: 'http://localhost:4000/graphql',
wsEndpoint: 'ws://localhost:4000/graphql'
}
}
}
The function to get the cats:
private getCats() {
this.$apollo.query({ query: GET_CATS_QUERY }).then((res:any) => {
alert(JSON.stringify(res.data, null, 0));
});
}
How can I disable the cache or is there an other solution?
I had a similar problem recently and managed to fix it by creating a Nuxt plugin which overrides default client's options:
// plugins/apollo-overrides.ts
import { Plugin } from '#nuxt/types';
const apolloOverrides: Plugin = ({ app }) => {
// disable caching on all the queries
app.apolloProvider.defaultClient.defaultOptions = {
query: {
fetchPolicy: 'no-cache',
},
};
};
export default apolloOverrides;
Don't forget to register it in Nuxt's config:
// nuxt.config.js
export default {
...
plugins: [
'~/plugins/apollo-overrides',
],
...
};
I had problem like this you can fix it easily with remove $ before query
defaultOptions: {
query: {
fetchPolicy: 'no-cache',
errorPolicy: 'all'
}
},
And Reopen your dev server
If this solution not working add fetch policy for each query
.query({
query: sample,
variables: {},
errorPolicy: "all",
fetchPolicy: "no-cache"
})

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 cache using apollo-server

The apollo basic example at https://www.apollographql.com/docs/apollo-server/features/data-sources.html#Implementing-your-own-cache-backend they state that doing a redis cache is as simple as:
const { RedisCache } = require('apollo-server-cache-redis');
const server = new ApolloServer({
typeDefs,
resolvers,
cache: new RedisCache({
host: 'redis-server',
// Options are passed through to the Redis client
}),
dataSources: () => ({
moviesAPI: new MoviesAPI(),
}),
});
When I look at the examples of non-redis, it states that it's a simple { get, set } for cache. This means I should theoretically be able to do.
cache : {
get : function() {
console.log("GET!");
},
set : function() {
console.log("SET!");
}
}
No matter what I try, my cache functions are never called when I'm utilizing the graphQL explorer that apollo-server provides natively.
I have tried with cacheControl : true and with cacheControl set like it is in https://medium.com/brikl-engineering/serverless-graphql-cached-in-redis-with-apollo-server-2-0-f491695cac7f . Nothing.
Is there an example of how to implement basic caching in Apollo that does not utilize the paid Apollo Engine system?
You can look at the implementation of this package which caches the full response to implement your own cache.
import { RedisCache } from "apollo-server-redis";
import responseCachePlugin from "apollo-server-plugin-response-cache";
const server = new ApolloServer({
...
plugins: [responseCachePlugin()],
cache: new RedisCache({
connectTimeout: 5000,
reconnectOnError: function(err) {
Logger.error("Reconnect on error", err);
const targetError = "READONLY";
if (err.message.slice(0, targetError.length) === targetError) {
// Only reconnect when the error starts with "READONLY"
return true;
}
},
retryStrategy: function(times) {
Logger.error("Redis Retry", times);
if (times >= 3) {
return undefined;
}
return Math.min(times * 50, 2000);
},
socket_keepalive: false,
host: "localhost",
port: 6379,
password: "test"
}),
});
You should be able to use the NPM package 'apollo-server-caching' by implementing your own interface. See Implementing Your Own Cache which provides an example.

Resources