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

Remove query #10

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.3.0] - 2020-02-25

### Added

- add `QueryRequest.updateCacheHandlerData`

### Changed

- update `QueryRequest` context to use Request context
- update `req_builder` to use new URI fragments

### Removed

- removed `Query` widget

## [0.2.1] - 2020-02-22

### Changed
Expand Down
79 changes: 34 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@
- [Build Generated Queries](#build-generated-queries)
- [Queries](#queries)
- [Mutations](#mutations)
- [With Flutter Widget](#with-flutter-widget)
- [With Flutter](#with-flutter)

# Features

| Feature | Progress |
| :--------------------------------------------------------------------------------------------------- | :------: |
| Generated Fully Typed Queries and Resposnes (using `gql_build`) | ✅ |
| Customizable `Link`s (using `gql_link`) | ✅ |
| Optimistic Cache | ✅ |
| Multiple data stores, including `MemoryStore` and `HiveStore` (using `hive` for offline persistence) | ✅ |
| Update queries with additinal data (e.g. for pagination) | ✅ |
| Flutter Widget | ✅ |
| Generated Fully Typed Queries and Resposnes (using `gql_build`) | ✅ |
| Customizable `Link`s (using `gql_link`) | ✅ |
| Optimistic Cache | ✅ |
| Multiple data stores, including `MemoryStore` and `HiveStore` (using `hive` for offline persistence) | ✅ |
| Update queries with additinal data (e.g. for pagination) | ✅ |
| Compatible with Flutter | ✅ |
| Offline Mutations | 🔜 |

# Architecture

1. **Code Builders** (from `gql_build`):
1. Create dart representations of all queries (including their variables, inputs, and data)
2. Using the additional `req_builder` included with this package, generate typed `QueryRequest` objects which allow the client to parse typed responses.
2. **Client**:
2. **Client**:
1. Handles configuration
2. Routes `QueryRequest`s to the cache or network, based on the given `FetchPolicy`
3. Generates streams of `QueryResponse`s for a given `QueryRequest`
Expand All @@ -53,7 +53,6 @@
2. Maintains a collection of Optimistic Patches and handles optimistic reads and writes
5. **Store**: Persists data


# Usage

## Setup Client
Expand Down Expand Up @@ -138,6 +137,7 @@ final client = Client(
options: options,
);
```

This handler can then be called using its key `"MyHandlerKey"` from a `QueryRequest`.

## Generate Dart GraphQL Files
Expand Down Expand Up @@ -213,7 +213,9 @@ Now we can build our dart generated files by calling:
```sh
pub run build_runner build
```

Or, if we are using flutter

```sh
flutter pub run build_runner build
```
Expand Down Expand Up @@ -249,9 +251,7 @@ client
.then((response) => print(response));
```

## With Flutter Widget

The library includes a `Query` flutter widget, which is a simple wrapper around the `StreamBuilder` widget.
## With Flutter

This example assumes we've registered our `Client` instance with `get_it`, but you can use any dependency injection.

Expand All @@ -260,8 +260,9 @@ import 'package:flutter/material.dart';
import 'package:ferry/ferry.dart';
import 'package:get_it/get_it.dart';

import './my_query.data.gql.dart';
import './my_query.req.gql.dart';
import './graphql/all_pokemon.data.gql.dart';
import './graphql/all_pokemon.req.gql.dart';
import './pokemon_card.dart';

class AllPokemonScreen extends StatelessWidget {
final client = GetIt.I<Client>();
Expand All @@ -272,39 +273,28 @@ class AllPokemonScreen extends StatelessWidget {
appBar: AppBar(
title: Text('All Pokemon'),
),
body: Query(
client: client,
queryRequest: AllPokemon(
buildVars: (vars) => vars..first = 500,
body: StreamBuilder(
stream: client.responseStream(
AllPokemon(
buildVars: (vars) => vars..first = 500,
),
),
builder: (BuildContext context, QueryResponse<$AllPokemon> response) {
if (response.loading)
return Center(child: CircularProgressIndicator());

final pokemons = response.data?.pokemons ?? [];
builder: (
BuildContext context,
AsyncSnapshot<QueryResponse<$AllPokemon>> snapshot,
) {
final response = snapshot.data;
if (response != null && response.loading)
return Center(
child: CircularProgressIndicator(),
);

final pokemons = response?.data?.pokemons ?? [];

return ListView.builder(
itemCount: pokemons.length,
itemBuilder: (context, index) => Card(
child: InkWell(
onTap: () => Navigator.of(context)
.pushNamed('detail', arguments: {'id': pokemon.id}),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
SizedBox(
child: Ink.image(image: NetworkImage(pokemon.image)),
height: 200,
width: 200,
),
Text(pokemon.name, style: Theme.of(context).textTheme.title),
Text('HP: ${pokemon.maxHP}',
style: Theme.of(context).textTheme.subhead)
],
),
),
),
itemBuilder: (context, index) => PokemonCard(
pokemon: pokemons[index],
),
);
},
Expand All @@ -314,7 +304,6 @@ class AllPokemonScreen extends StatelessWidget {
}
```


[license-badge]: https://img.shields.io/github/license/gql-dart/ferry.svg?style=flat-square
[license-link]: https://github.com/gql-dart/ferry/blob/master/LICENSE
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
Expand All @@ -324,4 +313,4 @@ class AllPokemonScreen extends StatelessWidget {
[github-star-badge]: https://img.shields.io/github/stars/gql-dart/ferry.svg?style=flat-square&logo=github&logoColor=ffffff
[github-star-link]: https://github.com/gql-dart/ferry/stargazers
[pub-badge]: https://img.shields.io/pub/v/ferry?logo=dart
[pub-link]: https://pub.dev/packages/ferry
[pub-link]: https://pub.dev/packages/ferry
23 changes: 15 additions & 8 deletions example/lib/src/all_pokemon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,23 @@ class AllPokemonScreen extends StatelessWidget {
appBar: AppBar(
title: Text('All Pokemon'),
),
body: Query(
client: client,
queryRequest: AllPokemon(
buildVars: (vars) => vars..first = 500,
body: StreamBuilder(
stream: client.responseStream(
AllPokemon(
buildVars: (vars) => vars..first = 500,
),
),
builder: (BuildContext context, QueryResponse<$AllPokemon> response) {
if (response.loading)
return Center(child: CircularProgressIndicator());
builder: (
BuildContext context,
AsyncSnapshot<QueryResponse<$AllPokemon>> snapshot,
) {
final response = snapshot.data;
if (response != null && response.loading)
return Center(
child: CircularProgressIndicator(),
);

final pokemons = response.data?.pokemons ?? [];
final pokemons = response?.data?.pokemons ?? [];

return ListView.builder(
itemCount: pokemons.length,
Expand Down
17 changes: 10 additions & 7 deletions example/lib/src/graphql/all_pokemon.req.gql.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import 'package:gql_example_flutter/src/graphql/all_pokemon.data.gql.dart'
as _i2;
import 'package:gql_example_flutter/src/graphql/all_pokemon.var.gql.dart'
as _i3;
import 'package:gql_example_flutter/src/graphql/all_pokemon.op.gql.dart' as _i4;
import 'package:uuid/uuid.dart' as _i5;
import 'package:gql_exec/gql_exec.dart' as _i4;
import 'package:gql_example_flutter/src/graphql/all_pokemon.op.gql.dart' as _i5;
import 'package:uuid/uuid.dart' as _i6;

class AllPokemon extends _i1.QueryRequest<_i2.$AllPokemon> {
AllPokemon(
Expand All @@ -13,18 +14,20 @@ class AllPokemon extends _i1.QueryRequest<_i2.$AllPokemon> {
_i2.$AllPokemon Function(_i2.$AllPokemon, _i2.$AllPokemon) updateResult,
Map<String, dynamic> optimisticResponse,
updateCacheHandlerKey,
Map<String, dynamic> context,
Map<String, dynamic> updateCacheHandlerData,
_i4.Context context,
_i1.FetchPolicy fetchPolicy})
: super(
operation: _i4.AllPokemon,
operation: _i5.AllPokemon,
variables: buildVars != null
? buildVars(_i3.AllPokemonVarBuilder()).variables
: {},
queryId: queryId != null ? queryId : _i5.Uuid().v4(),
: const {},
context: context != null ? context : const _i4.Context(),
queryId: queryId != null ? queryId : _i6.Uuid().v4(),
updateResult: updateResult,
optimisticResponse: optimisticResponse,
updateCacheHandlerKey: updateCacheHandlerKey,
context: context,
updateCacheHandlerData: updateCacheHandlerData,
fetchPolicy: fetchPolicy);

_i2.$AllPokemon parseData(Map<String, dynamic> json) => _i2.$AllPokemon(json);
Expand Down
17 changes: 10 additions & 7 deletions example/lib/src/graphql/pokemon_detail.req.gql.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import 'package:gql_example_flutter/src/graphql/pokemon_detail.data.gql.dart'
as _i2;
import 'package:gql_example_flutter/src/graphql/pokemon_detail.var.gql.dart'
as _i3;
import 'package:gql_exec/gql_exec.dart' as _i4;
import 'package:gql_example_flutter/src/graphql/pokemon_detail.op.gql.dart'
as _i4;
import 'package:uuid/uuid.dart' as _i5;
as _i5;
import 'package:uuid/uuid.dart' as _i6;

class PokemonDetail extends _i1.QueryRequest<_i2.$PokemonDetail> {
PokemonDetail(
Expand All @@ -16,18 +17,20 @@ class PokemonDetail extends _i1.QueryRequest<_i2.$PokemonDetail> {
updateResult,
Map<String, dynamic> optimisticResponse,
updateCacheHandlerKey,
Map<String, dynamic> context,
Map<String, dynamic> updateCacheHandlerData,
_i4.Context context,
_i1.FetchPolicy fetchPolicy})
: super(
operation: _i4.PokemonDetail,
operation: _i5.PokemonDetail,
variables: buildVars != null
? buildVars(_i3.PokemonDetailVarBuilder()).variables
: {},
queryId: queryId != null ? queryId : _i5.Uuid().v4(),
: const {},
context: context != null ? context : const _i4.Context(),
queryId: queryId != null ? queryId : _i6.Uuid().v4(),
updateResult: updateResult,
optimisticResponse: optimisticResponse,
updateCacheHandlerKey: updateCacheHandlerKey,
context: context,
updateCacheHandlerData: updateCacheHandlerData,
fetchPolicy: fetchPolicy);

_i2.$PokemonDetail parseData(Map<String, dynamic> json) =>
Expand Down
28 changes: 18 additions & 10 deletions example/lib/src/pokemon_detail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,31 @@ class PokemonDetailScreen extends StatelessWidget {

@override
Widget build(BuildContext context) {
return Query(
client: client,
queryRequest: PokemonDetail(
buildVars: (vars) => vars..id = id,
return StreamBuilder(
stream: client.responseStream(
PokemonDetail(
buildVars: (vars) => vars..id = id,
),
),
builder: (BuildContext context, QueryResponse<$PokemonDetail> response) {
if (response.loading)
builder: (
BuildContext client,
AsyncSnapshot<QueryResponse<$PokemonDetail>> snapshot,
) {
final response = snapshot.data;
if (response != null && response.loading)
return Scaffold(
appBar: AppBar(),
body: Center(child: CircularProgressIndicator()));
appBar: AppBar(),
body: Center(
child: CircularProgressIndicator(),
),
);

final pokemon = response.data?.pokemon;
final pokemon = response?.data?.pokemon;

return Scaffold(
appBar: AppBar(
title: Text(
pokemon?.name,
pokemon?.name ?? "",
)),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dependencies:
sdk: flutter
gql_link: ^0.2.1
gql_http_link: ^0.2.2
ferry: ^0.2.0
ferry: ^0.3.0
hive: ^1.3.0
hive_flutter: ^0.3.0+1
get_it: ^3.1.0
Expand Down
2 changes: 0 additions & 2 deletions lib/ferry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export './src/client/query_response.dart';
export './src/client/query_request.dart';
export './src/client/fetch_policy.dart';
export './src/cache/cache.dart';
export './src/cache/options.dart';
export './src/cache/cache_proxy.dart';
export './src/widgets/query.dart';
export './src/store/hive_store.dart';
export './src/store/memory_store.dart';
Loading