Skip to content

Commit

Permalink
[feature/Apollo] Upgrade to Apollo Client 2.0 (#1492)
Browse files Browse the repository at this point in the history
* ⬆️ Upgrade to Apollo Client 2.0
* Tweak HttpLink Credentials
* Fix Layout test
  • Loading branch information
tim-soft authored and langpavel committed Jan 5, 2018
1 parent 61bdcae commit a65988a
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 122 deletions.
14 changes: 9 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@
},
"browserslist": [">1%", "last 4 versions", "Firefox ESR", "not ie < 9"],
"dependencies": {
"apollo-client": "^1.7.0",
"apollo-cache-inmemory": "^1.1.4",
"apollo-client": "^2.0.4",
"apollo-link-error": "^1.0.3",
"apollo-link-http": "^1.3.2",
"apollo-link-schema": "^1.0.1",
"babel-polyfill": "^6.23.0",
"bluebird": "^3.5.0",
"body-parser": "^1.17.2",
"classnames": "^2.2.5",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"express": "^4.15.3",
"express-graphql": "^0.6.6",
"express-graphql": "^0.6.11",
"express-jwt": "^5.3.0",
"graphql": "^0.10.3",
"graphql-tag": "^2.4.2",
"graphql": "0.11.7",
"graphql-tag": "^2.6.1",
"history": "^4.6.3",
"isomorphic-style-loader": "^4.0.0",
"jsonwebtoken": "^7.4.1",
Expand All @@ -31,7 +35,7 @@
"prop-types": "^15.5.10",
"query-string": "^5.0.0",
"react": "^15.5.4",
"react-apollo": "^1.4.3",
"react-apollo": "^2.0.4",
"react-dom": "^15.5.4",
"react-redux": "^5.0.5",
"redux": "^3.7.1",
Expand Down
2 changes: 1 addition & 1 deletion src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const context = {
client: apolloClient,
// Initialize a new Redux store
// http://redux.js.org/docs/basics/UsageWithReact.html
store: configureStore(window.App.state, { apolloClient, fetch, history }),
store: configureStore(window.App.state, { fetch, history }),
fetch,
storeSubscription: null,
};
Expand Down
9 changes: 8 additions & 1 deletion src/components/Layout/Layout.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import React from 'react';
import renderer from 'react-test-renderer';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import createApolloClient from '../../core/createApolloClient';
import createFetch from '../../createFetch';
import App from '../App';
import Layout from './Layout';

Expand All @@ -24,9 +26,14 @@ const initialState = {};
describe('Layout', () => {
test('renders children correctly', () => {
const store = mockStore(initialState);
const client = createApolloClient();
const fetch = createFetch(self.fetch, {
baseUrl: 'test',
});

const wrapper = renderer
.create(
<App context={{ insertCss: () => {}, store }}>
<App context={{ insertCss: () => {}, store, client, fetch }}>
<Layout>
<div className="child" />
</Layout>
Expand Down
38 changes: 27 additions & 11 deletions src/core/createApolloClient/createApolloClient.client.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { from } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { HttpLink } from 'apollo-link-http';

const client = new ApolloClient({
networkInterface: createNetworkInterface({
const link = from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.warn(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) console.warn(`[Network error]: ${networkError}`);
}),
new HttpLink({
uri: '/graphql',
opts: {
// Additional fetch options like `credentials` or `headers`
credentials: 'include',
},
credentials: 'include',
}),
queryDeduplication: true,
reduxRootSelector: state => state.apollo,
});
]);

const cache = new InMemoryCache();

export default function createApolloClient() {
return client;
return new ApolloClient({
link,
cache: cache.restore(window.__APOLLO_CLIENT__), // eslint-disable-line no-underscore-dangle
ssrMode: true,
queryDeduplication: true,
connectToDevTools: true,
});
}
62 changes: 21 additions & 41 deletions src/core/createApolloClient/createApolloClient.server.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,27 @@
import { validate, execute, specifiedRules } from 'graphql';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { from } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { SchemaLink } from 'apollo-link-schema';

import ApolloClient from 'apollo-client';
export default function createApolloClient(schema) {
const link = from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.warn(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) console.warn(`[Network error]: ${networkError}`);
}),
new SchemaLink({ ...schema }),
]);

// Execute all GraphQL requests directly without
class ServerInterface {
constructor(optionsData) {
this.schema = optionsData.schema;
this.optionsData = optionsData;
}

async query({ query, variables, operationName }) {
try {
let validationRules = specifiedRules;
const customValidationRules = this.optionsData.validationRules;
if (customValidationRules) {
validationRules = validationRules.concat(customValidationRules);
}

const validationErrors = validate(this.schema, query, validationRules);
if (validationErrors.length > 0) {
return { errors: validationErrors };
}

const result = await execute(
this.schema,
query,
this.optionsData.rootValue,
this.optionsData.context,
variables,
operationName,
);

return result;
} catch (contextError) {
return { errors: [contextError] };
}
}
}

export default function createApolloClient(options) {
return new ApolloClient({
reduxRootSelector: state => state.apollo,
networkInterface: new ServerInterface(options),
link,
cache: new InMemoryCache(),
ssrMode: true,
queryDeduplication: true,
});
}
3 changes: 1 addition & 2 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { combineReducers } from 'redux';
import user from './user';
import runtime from './runtime';

export default function createRootReducer({ apolloClient }) {
export default function createRootReducer() {
return combineReducers({
apollo: apolloClient.reducer(),
user,
runtime,
});
Expand Down
2 changes: 1 addition & 1 deletion src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ app.get('*', async (req, res, next) => {

const store = configureStore(initialState, {
cookie: req.headers.cookie,
apolloClient,
fetch,
// I should not use `history` on server.. but how I do redirection? follow universal-router
history: null,
Expand Down Expand Up @@ -204,6 +203,7 @@ app.get('*', async (req, res, next) => {
data.app = {
apiUrl: config.api.clientUrl,
state: context.store.getState(),
__APOLLO_STATE__: context.client.extract(),
};

const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);
Expand Down
16 changes: 3 additions & 13 deletions src/store/configureStore.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import createRootReducer from '../reducers';
import createHelpers from './createHelpers';
import createLogger from './logger';

export default function configureStore(initialState, config) {
const helpers = createHelpers(config);
const { apolloClient } = config;

const middleware = [
thunk.withExtraArgument(helpers),
apolloClient.middleware(),
];
export default function configureStore(initialState) {
const middleware = [];

let enhancer;

Expand All @@ -29,9 +21,7 @@ export default function configureStore(initialState, config) {
enhancer = applyMiddleware(...middleware);
}

const rootReducer = createRootReducer({
apolloClient,
});
const rootReducer = createRootReducer();

// See https://github.com/rackt/redux/releases/tag/v3.1.0
const store = createStore(rootReducer, initialState, enhancer);
Expand Down
Loading

0 comments on commit a65988a

Please sign in to comment.