Having some trouble upgrading from 1.0 to 2.0.
First I ran:
meteor npm i --save apollo-client@beta apollo-cache-inmemory@beta apollo-link-http@beta
Then I updated my file as below:
My previous config:
import ApolloClient from 'apollo-client';
import { meteorClientConfig } from 'meteor/apollo';
const client = new ApolloClient({
...meteorClientConfig(),
dataIdFromObject: (o) => {
if (o.__typename && o._id)
return `${o.__typename}-${o._id}`;
return null;
},
});
export default client;
My new config:
import ApolloClient from 'apollo-client';
import Link from 'apollo-link-http';
import Cache from 'apollo-cache-inmemory';
import { meteorClientConfig } from 'meteor/apollo';
const cache = new Cache({
dataIdFromObject: (o) => {
if (o.__typename && o._id)
return `${o.__typename}-${o._id}`;
return null;
},
});
const client = new ApolloClient({
link: new Link({ uri: 'http://localhost:3000' }),
cache: cache.restore(window.__APOLLO_STATE || {}),
});
export default client;
In graphiql I get this error:
{
"errors": [
{
"message": "Unknown operation named \"null\"."
}
]
}
In the console when going to localhost I get:
modules.js?hash=7e87ea7a3f80914f1259a3df9e77c78fcc3b994c:52815 Uncaught (in promise) Error: Network error: Network request failed to return valid JSON
at new ApolloError (modules.js?hash=7e87ea7a3f80914f1259a3df9e77c78fcc3b994c:52815)
at modules.js?hash=7e87ea7a3f80914f1259a3df9e77c78fcc3b994c:53605
at meteor.js?hash=6d285d84547b3dad9717a7c89c664b61b45ea3d8:1117
at <anonymous>
Previous I was on:
"apollo-client": "^1.4.2",
Also, I'm not fully sure how this line fits into Apollo 2.0 setup:
import { meteorClientConfig } from 'meteor/apollo';
@elie222 I think your uri is incorrected base on this line. https://github.com/apollographql/meteor-integration/blob/master/src/main-client.js#L10
And you have to using apollo-link-set-context
to set custom token from meteor.
request.options.headers['meteor-login-token'] = meteorLoginToken;
Fortunately, meteorLoginToken
was exported. So:
import { meteorClientConfig, meteorLoginToken } from 'meteor/apollo';
import SetContextLink from 'apollo-link-set-context';
new SetContextLink((context) => ({
...context,
headers: {
...context.headers,
'meteor-login-token': meteorLoginToken(meteorClientConfig()),
},
})),
Following document at here: https://github.com/apollographql/apollo-link/blob/master/docs/summary.md#authentication
Here is an official upgrade guide if anyone else runs into this! https://github.com/apollographql/apollo-client/blob/master/Upgrade.md#upgrading-from-custom-networkinteface-with-middleware--afterware
If anyone else comes across this, this is how I had to configure the apollo client and server to get this to work:
// graphql/client.js
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import ApolloClient from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import HttpLink from 'apollo-link-http';
import Cache from 'apollo-cache-inmemory';
const httpLink = new HttpLink({ uri: '/graphql' });
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
'meteor-login-token': Accounts._storedLoginToken(),
},
});
return forward(operation);
});
const link = middlewareLink.concat(httpLink);
const client = new ApolloClient({
link,
cache: new Cache().restore(window.__APOLLO_STATE__),
});
export default client;
// graphql/server.js
import { createApolloServer } from 'meteor/apollo';
import { makeExecutableSchema } from 'graphql-tools';
import { typeDefs } from './schemas';
import { resolvers } from './resolvers';
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
createApolloServer({
schema,
});
The createApolloServer
function looks for a header named meteor-login-token
and uses it attach a user object to the context.
thanks, for the client side code I had to update a couple lines:
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
and
cache: new InMemoryCache().restore(window.__APOLLO_STATE__),
It appears that this entire issue thread is now out-of-date. I came across it when doing an internet search and was going to follow some of the recommendations. In order to prevent other people from finding this thread and wasting time playing around with outdated techniques, I will outline the latest best practices.
apollographql/meteor-integration is now at version 3.0.0. It has MeteorAccountsLink
for client-side and getUser()
for server-side. There is a simple implementation at https://github.com/lorensr/test-meteor-apollo.
There is now Apollo Server 2 with Data Sources which facilitates separation of application layer and data layer. You can see a simple example of using SQL here:
https://github.com/apollographql/fullstack-workshop-server/blob/datasources/src/datasources/LikesDB.js
The ApolloServer
constructor now has a dataSources
option. e.g.:
import { DSBooks } from "./DSBooks.js"
import { getUser } from 'meteor/apollo'
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => ({
dsBooks: new DSBooks()
}),
context: async ({ req }) => ({
user: await getUser(req.headers.authorization)
})
})
All boiler plates or starter kits should now implement these new concepts and syntax in order to follow best practice.
Documentation like Integrating with Meteor needs to be updated.
Thanks @tab00 - there is an open PR for this: https://github.com/apollographql/apollo-client/pull/3739
We'll be getting it merged shortly. One thing to note - you might want to also check out https://github.com/Swydo/ddp-apollo. It's excellent.
there is an open PR for this
That's great, @hwillson. I hope it will show new syntax for Subscriptions using https://github.com/apollographql/subscriptions-transport-ws (with websocket link, without SubscriptionManager
, and with SubscriptionServer
), as I've been having trouble getting it working and have been looking around. The new documentation that you refer to still has old code.
I've been using https://github.com/Swydo/ddp-apollo for a while and it has been great. Subscriptions work well via DDPLink
and is so easy to set up (very little code) in comparison to the normal official way. But I think ddp-apollo is now incompatible with the new datasources in Apollo Server 2, which is why I have been looking around.
I looked at cult-of-coders/apollo but their subscription syntax ("live queries") looks different to the standard Apollo Subscriptions syntax, which would make it difficult to refactor in future to use the official packages. With ddp-apollo you could use all the same standard Subscriptions syntax.
Most helpful comment
If anyone else comes across this, this is how I had to configure the apollo client and server to get this to work:
The
createApolloServer
function looks for a header namedmeteor-login-token
and uses it attach a user object to the context.