Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apollo Client 2.0 [Beta] #1941

Merged
merged 0 commits into from
Sep 13, 2017
Merged

Apollo Client 2.0 [Beta] #1941

merged 0 commits into from
Sep 13, 2017

Conversation

jbaxleyiii
Copy link
Contributor

@jbaxleyiii jbaxleyiii commented Jul 24, 2017

tldr;

The 2.0 version of Apollo is targeting a more customizable experience with GraphQL. It prioritizes features like custom execution chains (using Apollo Link) and custom stores while providing powerful defaults. It will be an overall minor change to the API so you won't have to change very much code in your current app at all! Apollo ❤️ backwards compat

About

The 2.* version of Apollo Client builds on the original principles of the project. For reference, those goals are:

  1. Incrementally adoptable, so that you can drop it into an existing JavaScript app and start using GraphQL for just part of your UI.
  2. Universally compatible, so that Apollo works with any build setup, any GraphQL server, and any GraphQL schema.
  3. Simple to get started with, you can start loading data right away and learn about advanced features later.
  4. Inspectable and understandable, so that you can have great developer tools to understand exactly what is happening in your app.
  5. Built for interactive apps, so your users can make changes and see them reflected in the UI immediately.
  6. Small and flexible, so you don't get stuff you don't need. The core is under 25kb compressed.
  7. Community driven, Apollo is driven by the community and serves a variety of use cases. Everything is planned and developed in the open.

Based on feedback from a wide variety of users, the 2.* version will double down on being incrementally adoptable and flexible by allowing much stronger extension points. Customization of the client (i.e. data store, execution chain, etc) will be first class in the revised API. The next version will also take steps to reduce the overall size of the default client and provide the foundations for Apollo powering more of the application experience from development to production (i.e. client side state management).

The goal of the 2.0 launch is not to provide all of the new features that have been asked to be built in. Instead, the 2.0 launch makes a few key changes to both management of the code base (lerna / small modules) and the changes necessary to support custom stores and links fully. Apollo Client 2.0 is the jumping off point for user-land driven innovation (custom stores, custom links) and internal refactor (moving query manager into links, breaking apart the store / links into packages, etc)

Details

There are three main tasks for the 2.0 version.

  • new Store API design and default implementation
  • deprecate NetworkInterface in favor of Apollo Link
  • rework repo to allow for smaller packages / easier contributions

Immediate wins

  • retrying queries on flaky networks
  • support in place to handle offline interactions
  • faster default store
  • ability to build stores for things like mobx, redux, ng-rx, vuex, and more!
  • smaller bundle size

Contributing

If you are interested in contributing to the 2.0 release that is SO great!! There are a number of ways to help out! Please comment on this PR if you want to do any of the following!

  • implement any of the main features
  • test out the 2.0 in your application (in a prerelease version)
  • write a custom link
  • write a custom store
  • help with documentation and upgrade guides (even a codemod maybe!)

Installation instructions

The 2.0 of apollo is split into a few packages. To try it out in your app you can install the following

npm i --save apollo-client@alpha apollo-cache-inmemory@alpha apollo-link

This will give you the replacement for networkInterfaces (links), the current apollo-cache (cache-inmemory) and the new client.

For updating your app, you should only need to change the constructor. For example, a meteor SSR app that looked like this:

import { render } from 'react-dom';
import { onPageLoad } from 'meteor/server-render';

// apollo imports
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider } from 'react-apollo';

import { App } from '/imports/app';

export const start = () => {
  const client = new ApolloClient({
    networkInterface: createNetworkInterface({ uri: 'http://localhost:3000' }),
    initialState: { apollo: window.__APOLLO_STATE__ },
  });

  const WrappedApp = (
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );

  render(WrappedApp, document.getElementById('app'));
};

onPageLoad(start);

Now looks like this:

import { render } from 'react-dom';
import { onPageLoad } from 'meteor/server-render';

// apollo imports
import ApolloClient from 'apollo-client';
import Link from 'apollo-link-http';
import Cache from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo';

import { App } from '/imports/app';

export const start = () => {
  const client = new ApolloClient({
    link: new Link({ uri: 'http://localhost:3000' }),
    cache: new Cache(window.__APOLLO_STATE__),
  });

  // XXX this will have to be updated in react-apollo
  client.initStore = () => {}

  const WrappedApp = (
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );

  render(WrappedApp, document.getElementById('app'));
};

onPageLoad(start);

The upgrade path revolves around replacing networkInterface with a link and initial state with a cache.

Happy testing!

@jbaxleyiii jbaxleyiii self-assigned this Jul 24, 2017
@mention-bot
Copy link

@jbaxleyiii, thanks for your PR! By analyzing the history of the files in this pull request, we identified @kamilkisiela, @stubailo and @michalkvasnicak to be potential reviewers.

@apollo-cla
Copy link

apollo-cla commented Jul 24, 2017

Warnings
⚠️

❗ Big PR

Messages
📖

Please add your name and email to the AUTHORS file (optional)

📖

If this was a change that affects the external API, please update the docs and post a link to the PR in the discussion

Generated by 🚫 dangerJS

@jbaxleyiii
Copy link
Contributor Author

jbaxleyiii commented Aug 11, 2017

The first alpha is ready for release!

Installation

The 2.0 of apollo is split into a few packages. To try it out in your app you can install the following

npm i --save apollo-client@alpha apollo-cache-inmemory@alpha apollo-link

This will give you the replacement for networkInterfaces (links), the current apollo-cache (cache-inmemory) and the new client.

For updating your app, you should only need to change the constructor. For example, a meteor SSR app that looked like this:

import { render } from 'react-dom';
import { onPageLoad } from 'meteor/server-render';

// apollo imports
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider } from 'react-apollo';

import { App } from '/imports/app';

export const start = () => {
  const client = new ApolloClient({
    networkInterface: createNetworkInterface({ uri: 'http://localhost:3000' }),
    initialState: { apollo: window.__APOLLO_STATE__ },
  });

  const WrappedApp = (
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );

  render(WrappedApp, document.getElementById('app'));
};

onPageLoad(start);

Now looks like this:

import { render } from 'react-dom';
import { onPageLoad } from 'meteor/server-render';

// apollo imports
import ApolloClient from 'apollo-client';
import Link from 'apollo-link-http';
import Cache from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo';

import { App } from '/imports/app';

export const start = () => {
  const client = new ApolloClient({
    link: new Link({ uri: 'http://localhost:3000' }),
    cache: new Cache(window.__APOLLO_STATE__),
  });

  // XXX this will have to be updated in react-apollo
  client.initStore = () => {}

  const WrappedApp = (
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );

  render(WrappedApp, document.getElementById('app'));
};

onPageLoad(start);

The upgrade path revolves around replacing networkInterface with a link and initial state with a cache.

Known issues

Currently returning multiple results from links are not supported. Subscriptions should work, as should batching, all other link functionality.

React apollo has not been heavily tested against this release yet. Right off the bat, you will need to add

client.initStore = () => {}

after you create your client because ApolloProvider expects it to exist

Happy testing!

@jbaxleyiii
Copy link
Contributor Author

Fort those interested in what an upgrade will look like so far: https://github.com/jbaxleyiii/ReactNYC-SSR/pull/1/files?diff=split#diff-096103d8490b885f9d5037baea6aea80

@ctavan
Copy link

ctavan commented Aug 17, 2017

@jbaxleyiii thanks for all the work here!

Sorry for hijacking this thread, but I feel that 2.0 would be the opportunity to get rid of the global fetch polyfill: Have you had the chance to further discuss whether removing the polyfill from the default packages is an option for 2.0? See apollographql/apollo-fetch#30

@tnrich
Copy link
Contributor

tnrich commented Aug 17, 2017

@jbaxleyiii Could you provide more info about this:

Currently returning multiple results from links are not supported.

@jbaxleyiii
Copy link
Contributor Author

@ctavan I have seen it and I do agree! Fetch is removed from all core AC code and I will work to remove it from fetcher as well.

@tnrich one of the super cool things about the 2.0 is support for things like using the @live or @defer directives. These allow you to fire off an initial query, get results, then, at a later point, receive more data for the same query. In order for 2.0 to support this, the internals need to handle this event stream correctly.

@benbender
Copy link

Another question for the rising star of version 2.0: could it be possible to switch the link on a per query-basis?

Use-cases could be f.e. to have a default-link via WS and use another HTTP-Link for uploading and/or auth-handling via cookie...

With the new interfaces it could be possible, judging by a quick look - or am I on a completly wrong path here?

@DxCx
Copy link
Contributor

DxCx commented Aug 27, 2017

@benbender you should be able to build any logic with apollo-link split just like http+ws for subscription example

@furuholm
Copy link

Really looking forward to @defer being supported!

@jbaxleyiii what kind of server support will be required for @defer to work with apollo-client?

@DxCx
Copy link
Contributor

DxCx commented Aug 28, 2017

hey @furuholm,
i've put up an example repository showing how it can be achieved using graphql-rxjs engine along with apollo's websocket transport.
https://github.com/DxCx/graphql-rxjs-websocket-example

just npm install & start and you can test it over graphiql 🎉

@codecov
Copy link

codecov bot commented Sep 4, 2017

Codecov Report

❗ No coverage uploaded for pull request base (master@a70d458). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #1941   +/-   ##
=========================================
  Coverage          ?   83.99%           
=========================================
  Files             ?       35           
  Lines             ?     1949           
  Branches          ?      458           
=========================================
  Hits              ?     1637           
  Misses            ?      306           
  Partials          ?        6
Impacted Files Coverage Δ
packages/apollo-client/src/core/QueryManager.ts 91.66% <ø> (ø)
...ckages/apollo-client/src/util/subscribeAndCount.ts 100% <ø> (ø)
packages/apollo-client/src/core/ObservableQuery.ts 90.62% <ø> (ø)
packages/apollo-client/src/util/wrap.ts 59.09% <ø> (ø)
packages/apollo-cache-inmemory/src/index.ts 100% <ø> (ø)
packages/apollo-client/src/data/store.ts 96.61% <ø> (ø)
packages/apollo-client/src/core/types.ts 100% <ø> (ø)
packages/apollo-utilities/src/util/environment.ts 100% <ø> (ø)
packages/apollo-utilities/src/util/isEqual.ts 94.44% <ø> (ø)
...ackages/apollo-cache-inmemory/src/readFromStore.ts 92.4% <ø> (ø)
... and 25 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a70d458...9b0a587. Read the comment docs.

@s-panferov
Copy link

@jbaxleyiii I'm playing with 2.0.0-alpha.2 version you've released and I cannot find any way to specify customResolvers. Is this feature gone?

@stubailo
Copy link
Contributor

stubailo commented Sep 6, 2017

@s-panferov it shouldn't be gone, but we might have forgotten to expose it as a public API. Thanks for the feedback!

@stubailo
Copy link
Contributor

stubailo commented Sep 6, 2017

Looks like James added it here: dbe1639

@jbaxleyiii
Copy link
Contributor Author

@s-panferov I will publish an alpha today with it back in there! I'll comment when its out and how to use it!

@@ -190,7 +190,14 @@ export function writeSelectionSetToStore({
context,
});
} else {
if (context.fragmentMatcherFunction) {
// if this is a defered field we don't need to throw / wanr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some typos in this comment: warn/wanr; also deferred has two rs

@jbaxleyiii jbaxleyiii changed the title [DO NOT MERGE] Apollo Client 2.0 [Alpha] Apollo Client 2.0 Sep 12, 2017
@jbaxleyiii jbaxleyiii changed the title [Alpha] Apollo Client 2.0 Apollo Client 2.0 [Beta] Sep 13, 2017
@jbaxleyiii jbaxleyiii merged commit 9b0a587 into master Sep 13, 2017
@jbaxleyiii jbaxleyiii deleted the 2.0-alpha branch September 13, 2017 15:54
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.