Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lucasconstantino/apollo-progressive-fragment-matcher
A smart alternative to the introspection fragment matcher.
https://github.com/lucasconstantino/apollo-progressive-fragment-matcher
apollo apollo-client fragments graphql introspection
Last synced: 9 days ago
JSON representation
A smart alternative to the introspection fragment matcher.
- Host: GitHub
- URL: https://github.com/lucasconstantino/apollo-progressive-fragment-matcher
- Owner: lucasconstantino
- License: mit
- Created: 2019-04-15T20:39:53.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-05-31T00:19:41.000Z (over 4 years ago)
- Last Synced: 2024-10-31T21:22:53.609Z (16 days ago)
- Topics: apollo, apollo-client, fragments, graphql, introspection
- Language: JavaScript
- Size: 1.29 MB
- Stars: 20
- Watchers: 3
- Forks: 2
- Open Issues: 18
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Apollo Progressive Fragment Matcher
[![Version](https://img.shields.io/npm/v/apollo-progressive-fragment-matcher.svg?style=flat-square)](https://www.npmjs.com/package/apollo-progressive-fragment-matcher)
[![License](https://img.shields.io/npm/l/apollo-progressive-fragment-matcher.svg)](https://github.com/lucasconstantino/apollo-progressive-fragment-matcher/blob/master/package.json)
[![bundlephobia](https://badgen.net/bundlephobia/minzip/apollo-progressive-fragment-matcher@latest)](https://bundlephobia.com/result?p=apollo-progressive-fragment-matcher)
[![Build Status](https://travis-ci.org/lucasconstantino/apollo-progressive-fragment-matcher.svg?branch=master)](https://travis-ci.org/lucasconstantino/apollo-progressive-fragment-matcher)
[![codecov](https://codecov.io/gh/lucasconstantino/apollo-progressive-fragment-matcher/branch/master/graph/badge.svg)](https://codecov.io/gh/lucasconstantino/apollo-progressive-fragment-matcher)**A smart alternative to the introspection fragment matcher.**
---
## Motivation
> `Error: You are using the simple (heuristic) fragment matcher...` :scream:
GraphQL APIs are evolving, and usage of Unions and Interfaces are much more common now then they use to be. Some time ago this kind of feature was considered advanced; I don't think that's true today. The GraphQL clients all need a way to distinguish data between two or more fragments that rely on inherited types (unions & interfaces), what I call the _Human and Droid_ problem.
Apollo has [long solved this issue](https://github.com/apollographql/apollo-client/pull/1483) by providing the `IntrospectionFragmentMatcher`. This fragment matcher, though, requires, that you provide a `introspectionQueryResultData`, which is your API's [introspection query](https://graphql.org/learn/introspection/) result. Introspection queries result [can be huge](https://gist.github.com/lucasconstantino/87160d2bb7ef667eb958bee38c917382).
What if we could avoid pre-fetching the introspection? What if we could _introspect as we go_?
Welcome `ProgressiveFragmentMatcher`.
## Usage
### Installation
```
npm i apollo-progressive-fragment-matcher apollo-link graphql invariant
```### `ProgressiveFragmentMatcher`
The _Progressive Fragment Matcher_ has two strategies for matching fragment types:
Progressive introspection (default)
This strategy _transforms_ the outgoing queries to request introspection information on the requesting types. It does cache the results, meaning if on a second query you use the same fragment type, it won't introspect again (nor transform the query, which can be expensive).
> This strategy is much like what ApolloClient normally does to inject \_\_typename fields.
**Good**:
- Easy to install;
- Drop-in replacement for `IntrospectionFragmentMatcher`;**Bad**:
- Query transforms are expensive;
##### Usage
```js
import ApolloClient from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { from } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { ProgressiveFragmentMatcher } from 'apollo-progressive-fragment-matcher'const fragmentMatcher = new ProgressiveFragmentMatcher()
const client = new ApolloClient({
cache: new InMemoryCache({ fragmentMatcher }),
link: from([fragmentMatcher.link(), new HttpLink()]),
})
```Extension based
This strategy is very performatic on the client side, because it does not depend on query transformation. What this strategy does is send the server an extension flag (`{ possibleTypes: true }`) to request the server to send possible types of any returned type in the query - regardless of the fragments requested.
> This strategy requires you have control of the server, and currently only works with ApolloServer custom extensions implementation.
**Good**:
- Fast on client;
- Persisted queries supported;**Bad**:
- Requires server control;
##### Usage
**client:**
```js
import ApolloClient from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { from } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { ProgressiveFragmentMatcher } from 'apollo-progressive-fragment-matcher'const fragmentMatcher = new ProgressiveFragmentMatcher({
strategy: 'extension',
})const client = new ApolloClient({
cache: new InMemoryCache({ fragmentMatcher }),
link: from([fragmentMatcher.link(), new HttpLink()]),
})
```**server**
```js
import { ApolloServer } from 'apollo-server'
import { PossibleTypesExtension } from 'apollo-progressive-fragment-matcher'const server = new ApolloServer({
typeDefs,
resolvers,
extensions: [() => new PossibleTypesExtension()],
})server.listen() // start server
```> Due to a limitation on ApolloClient's customizing capabilities, both strategies require you append a link created from the fragment matcher instance.
## Warning :warning:
Although [well tested](https://codecov.io/github/lucasconstantino/apollo-progressive-fragment-matcher), this project is in an **experimental stage**.
### About persisted queries
I have not yet stressed it out on complicating circustances such as _persistend queries_. I've marked the `extension` strategy as supporting _persisted queries_ due to the nature of this operation - it relies on no query transformation, therefore _should_ be compatible with persisted queries, but no test prove this concept yet.