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

Merge Apollo Link common + HTTP functionality into core #5412

Merged
merged 30 commits into from
Oct 6, 2019

Conversation

hwillson
Copy link
Member

@hwillson hwillson commented Oct 4, 2019

Background

As part of Apollo Client 3's incremental steps towards improving developer experience, portions of the Apollo Link infrastructure are being moved into core. This will help ensure developers have much of what they need to build awesome GraphQL based applications out of the box, with Apollo Client. This will also help make future Apollo Link optimizations easier, due to its closer integration with the Apollo Client core.

Implementation

This PR introduces functionality into @apollo/client that is equivalent to the following Apollo Link packages:

  • apollo-link
  • apollo-link-http
  • apollo-link-http-common

This means installing and referencing the previously separate apollo-link and/or apollo-link-http packages is no longer necessary. ApolloLink and HttpLink are now exported directly from @apollo/client, and HTTP links can be created automatically using the ApolloClient uri constructor option:

import { ApolloClient, useQuery } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000'
});

function App() {
  const { loading, data } = useQuery(SOME_QUERY, { client });
  if (loading) return <p>Loading ...</p>;
  return <p>{data.something}</p>;
}

...etc

This approach is very similar to the now deprecated Apollo Boost project, but instead of offering a limited set of capabilities from a separate project, the goal is to simplify use of the main (and only) Apollo Client project (while providing options to incrementally add in more sophisticated functionality).

Apollo Link Project

Associated PR: apollographql/apollo-link#1158

PR apollographql/apollo-link#1158 updates the Apollo Link project to remove the capabilities that will be part of the AC core, after this PR is merged in. Packages in the apollo-link repo will have a dependency on Apollo Client, to pull in the common Apollo Link functionality they need.

Documentation

Apollo Client documentation changes for this work are coming in a separate PR. We're going to merge the separate Apollo Link documentation into the Apollo Client docs, which means there will be quite a few changes.

And remove the unused isomorphic fetch dep.
Introductory import of the Apollo Link core, common and HTTP
code that is going to be integrated into the Apollo Client core.
This code is going to change, but this commit gets the initial
code moved over, and ensures that all Link tests still pass.
Now that the HTTP link code is part of AC, we can open up the
constructor to allow additional options, like Apollo Boost did.
Most people will just want to use `uri`, but `credentials`
and `headers` use is common enough that it probably makes
sense to expose them as well. Other HTTP link options can
still be accessed by instantiating an `HttpLink` and passing
it in via AC's constructor `link` option. Defining a custom
link overrides the `uri`, `credentials`, and `headers` options.
The Apollo Link project will be updated to re-use common and
HTTP based link code from Apollo Client, so we need to make
sure that code is reachable externally.
This util was adding very little additional value over just using
`ApolloLink` directly.
Also removes link test utilities from the public API.
This should help make future refactoring a bit easier, and gets
us away from re-exporting all link utility functions, when very
few of them need to be made available outside of this project.
Smaller, more focused files should make it easier to refactor
AC's link support further. Link based re-exports from Apollo
Client have been adjusted at the same time, to make sure we're
only exporting items that are trully needed by 3rd party links
(and by the `apollo-link` repo).
I'm not sure what the historical reason was for exposing link
utility functions like `concat`, `empty`, `from`, `split` and
`execute` both as static functions on `ApolloLink` and as
separate importable functions. Since it might be a bit jarring
for people if we remove one of these options, for now lets
move all `ApolloLink` functionality back into the `ApolloLink`
class, and instead re-export that functionality as separate
utility functions. Using the utility functions through
`ApolloLink` seems to be the most popular approach, and by
aligning this in the code we'll make future maintenance a bit
easier.
Copy link
Member

@benjamn benjamn left a comment

Choose a reason for hiding this comment

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

Looks great! I will push a couple commits with minor tweaks that I spotted while reviewing.

src/react/testing/mocks/mockSubscriptionLink.ts Outdated Show resolved Hide resolved
package.json Show resolved Hide resolved
@benjamn benjamn added this to the Release 3.0 milestone Oct 4, 2019
@benjamn
Copy link
Member

benjamn commented Oct 4, 2019

@hwillson Before we merge this, can you update CHANGELOG.md to mention this PR?

Sub-classing then re-exporting `Observable` leads to the
`@types/zen-observable` types not being available, when
`Observable` is exported from `@apollo/client`. This is because
the `@types/zen-observable` class declaration
(`declare class Observable<T>`) is replaced during TS
compilation with the `class Observable extends LinkObservable`
declaration, which doesn't expose any of original
`Observable` methods. This means projects like Apollo Link
that are using the re-exported `Observable` from
`@apollo/client`, don't see any of the `Observable` methods
when using Typescript.

Instead of creating an `Observable` sub-class with the additional
RxJS interop functionality, this commit uses TS global module
augmentation to essentially add to the `@types/zen-observable`
`Observable` type. It then adds the needed interop function to
`Observable` directly. This allows external projects like
Apollo Link to find all `@types/zen-observable` types, and
keeps RxJS interop functionality in place.

And just to add - method creation using `$$observable` was
removed as `zen-observable` already does this:

https://github.com/zenparsing/zen-observable/blob/f63849a8c60af5d514efc8e9d6138d8273c49ad6/src/Observable.js#L396
Make sure all parts of Apollo Client import `Observable`
from a local module, instead of from `zen-observable`
directly. This decoupling will make things easier as we
investigate letting people use their own observables
implementation.
@hwillson hwillson merged commit c98a833 into release-3.0 Oct 6, 2019
@hwillson hwillson deleted the http-link-merge branch October 6, 2019 13:36
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants