Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Proposed API change #49

Merged
merged 9 commits into from
Oct 24, 2019
Merged
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
76 changes: 49 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ let client =
ReasonApollo.createApolloClient(~link=httpLink, ~cache=inMemoryCache, ());

let app =
<ReasonApolloHooks.ApolloProvider client>
<ApolloHooks.ApolloProvider client>
...
</ReasonApolloHooks.ApolloProvider>
</ApolloHooks.ApolloProvider>
```

### Usage with reason-apollo
Expand All @@ -50,9 +50,9 @@ let client = ... // create Apollo client

ReactDOMRe.renderToElementWithId(
<ReasonApollo.Provider client>
<ReasonApolloHooks.ApolloProvider client>
<ApolloHooks.ApolloProvider client>
<App />
</ReasonApolloHooks.ApolloProvider>
</ApolloHooks.ApolloProvider>
</ReasonApollo.Provider>,
"root",
);
Expand All @@ -63,20 +63,20 @@ ReactDOMRe.renderToElementWithId(
## useQuery

```reason
module UserQueryConfig = [%graphql {|
open ApolloHooks

module UserQuery = [%graphql {|
query UserQuery {
currentUser {
name
}
}
|}];

module UserQuery = ReasonApolloHooks.Query.Make(UserQueryConfig);

[@react.component]
let make = () => {
/* Both variant and records available */
let (simple, _full) = UserQuery.use();
let (simple, _full) = useQuery(~query=UserQuery.make(), ());

<div>
{
Expand All @@ -98,7 +98,7 @@ Using the `full` record for more advanced cases
[@react.component]
let make = () => {
/* Both variant and records available */
let (_simple, full) = UserQuery.use(());
let (_simple, full) = useQuery(~query=UserQuery.make(), ());

<div>
{
Expand All @@ -117,20 +117,21 @@ let make = () => {
Using `fetchPolicy` to change interactions with the `apollo` cache, see [apollo docs](https://www.apollographql.com/docs/react/api/react-apollo/#optionsfetchpolicy).

```reason
let (_simple, full) = UserQuery.use(~fetchPolicy=NetworkOnly, ());
let (_simple, full) = useQuery(~query=UserQuery.make(), ~fetchPolicy=NetworkOnly, ());
```

Using `errorPolicy` to change how errors are handled, see [apollo docs](https://www.apollographql.com/docs/react/api/react-apollo/#optionserrorpolicy).

```reason
let (simple, _full) = UserQuery.use(~errorPolicy=All, ());
let (simple, _full) = useQuery(~query=UserQuery.make(), ~errorPolicy=All, ());
```

Using `skip` to skip query entirely, see [apollo docs](https://www.apollographql.com/docs/react/api/react-apollo/#configskip).

```reason
let (simple, _full) =
UserQuery.use(
useQuery(
~query=UserQuery.make(),
~skip=
switch (val) {
| None => true
Expand All @@ -143,25 +144,48 @@ let (simple, _full) =
## useMutation

```reason
module ScreamMutationConfig = [%graphql {|
module ScreamMutation = [%graphql {|
mutation ScreamMutation($screamLevel: Int!) {
scream(level: $screamLevel) {
error
}
}
|}];

module ScreamMutation = ReasonApolloHooks.Mutation.Make(ScreamMutationConfig);
[@react.component]
let make = () => {
/* Both variant and records available */
let ( screamMutation, _simple, _full ) = useMutation(~mutation=ScreamMutation.make(~screamLevel=10, ()), ());
let scream = (_) => {
screamMutation()
|> Js.Promise.then_(result => {
switch(result) {
| Data(data) => ...
| Error(error) => ...
| NoData => ...
}
Js.Promise.resolve()
})
|> ignore
}

<div>
<button onClick={scream}>
{React.string("You kids get off my lawn!")}
</button>
</div>
}
```

If you don't know the value of the variables you can initialize with the query property

```reason
[@react.component]
let make = () => {
/* Both variant and records available */
let ( screamMutation, _simple, _full ) = ScreamMutation.use();
let ( screamMutation, _simple, _full ) = useMutation(~incompleteMutation=ScreamMutation.query, ());
let scream = (_) => {
screamMutation(
~variables=ScreamMutationConfig.make(~screamLevel=10, ())##variables,
()
)
screamMutation(~mutation=ScreamMutation.make(~screamLevel=10, ()), ())
|> Js.Promise.then_(result => {
switch(result) {
| Data(data) => ...
Expand Down Expand Up @@ -194,7 +218,7 @@ There are a couple of caveats with manual cache updates.
An example of cache update could look like this:

```reason
module PersonsQueryConfig = [%graphql
module PersonsQuery = [%graphql
{|
query getAllPersons {
allPersons {
Expand All @@ -206,16 +230,14 @@ module PersonsQueryConfig = [%graphql
|}
];

module PersonsQuery = ReasonApolloHooks.Query.Make(PersonsQueryConfig);

module PersonsReadQuery = ApolloClient.ReadQuery(PersonsQueryConfig);
module PersonsWriteQuery = ApolloClient.WriteQuery(PersonsQueryConfig);
module PersonsReadQuery = ApolloClient.ReadQuery(PersonsQuery);
module PersonsWriteQuery = ApolloClient.WriteQuery(PersonsQuery);

external cast: Js.Json.t => PersonsQueryConfig.t = "%identity";
external cast: Js.Json.t => PersonsQuery.t = "%identity";

let updatePersons = (~client, ~name, ~age) => {
let query = PersonsQueryConfig.make();
let readQueryOptions = ReasonApolloHooks.Utils.toReadQueryOptions(query);
let query = PersonsQuery.make();
let readQueryOptions = ApolloHooks.Utils.toReadQueryOptions(query);

// can throw exception of cache is empty
switch (PersonsReadQuery.readQuery(client, readQueryOptions)) {
Expand Down
1 change: 0 additions & 1 deletion bsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
}
],
"suffix": ".bs.js",
"namespace": true,
"bs-dependencies": ["reason-react", "reason-apollo"],
"refmt": 3
}
2 changes: 1 addition & 1 deletion examples/persons/bsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
],
"suffix": ".bs.js",
"namespace": true,
"ppx-flags": ["graphql_ppx/ppx"],
"ppx-flags": ["@baransu/graphql_ppx_re/ppx"],
"bs-dependencies": ["reason-react", "reason-apollo", "reason-apollo-hooks"],
"refmt": 3
}
10 changes: 5 additions & 5 deletions examples/persons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@
"author": "",
"license": "MIT",
"dependencies": {
"@apollo/react-hooks": "^3.0.0",
"react": "^16.8.1",
"react-dom": "^16.8.1",
"@apollo/react-hooks": "^3.1.1",
"react": "^16.10.1",
"react-dom": "^16.10.1",
"reason-apollo": "^0.17.0",
"reason-apollo-hooks": "../../",
"reason-react": ">=0.7.0"
},
"devDependencies": {
"bs-platform": "^5.0.6",
"bs-platform": "^5.2.0",
"css-loader": "^3.2.0",
"graphql_ppx": "^0.2.8",
"@baransu/graphql_ppx_re": "^0.3.2",
"html-webpack-plugin": "^3.2.0",
"style-loader": "^1.0.0",
"webpack": "^4.0.1",
Expand Down
22 changes: 9 additions & 13 deletions examples/persons/src/EditPerson.re
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
open ReasonApolloHooks;

module EditPersonConfig = [%graphql
module EditPersonMutation = [%graphql
{|
mutation updatePerson($id: ID!, $age: Int!, $name: String!) {
updatePerson(id: $id, age: $age, name: $name) {
Expand All @@ -12,8 +10,6 @@ module EditPersonConfig = [%graphql
|}
];

module EditPersonMutation = Mutation.Make(EditPersonConfig);

type state = {
id: string,
age: option(int),
Expand Down Expand Up @@ -42,19 +38,19 @@ let make = () => {
React.useReducer(reducer, {age: None, name: "", id: ""});

let (editPersonMutation, _simple, _full) =
EditPersonMutation.use(
ApolloHooks.useMutation(
~incompleteMutation=EditPersonMutation.query,
~refetchQueries=
_ => {
let query =
FilterByAge.PersonsOlderThanConfig.make(~age=filterAgeLimit, ());
[|ReasonApolloHooks.Utils.toQueryObj(query)|];
FilterByAge.PersonsOlderThanQuery.make(~age=filterAgeLimit, ());
[|ApolloHooks.Utils.toQueryObj(query)|];
},
~update=
(client, mutationResult) => {
let data =
mutationResult##data
->Belt.Option.flatMap(result => result##updatePerson);

switch (data) {
| Some(person) =>
FilterByNameCache.updateCache(client, person, filterName)
Expand All @@ -69,8 +65,8 @@ let make = () => {
switch (state.age) {
| Some(age) =>
editPersonMutation(
~variables=
EditPersonConfig.make(~id=state.id, ~age, ~name=state.name, ())##variables,
~mutation=
EditPersonMutation.make(~id=state.id, ~age, ~name=state.name, ()),
(),
)
|> ignore
Expand Down Expand Up @@ -110,7 +106,7 @@ let make = () => {
<div className="form-field">
<input
required=true
pattern="\d{1,3}"
pattern="\\d{1,3}"
placeholder="Age"
value={
state.age
Expand All @@ -134,4 +130,4 @@ let make = () => {
<FilterByNameCache name=filterName />
</div>
</div>;
};
};
14 changes: 4 additions & 10 deletions examples/persons/src/FilterByAge.re
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module PersonsOlderThanConfig = [%graphql
module PersonsOlderThanQuery = [%graphql
{|
query getPersonsOlderThan($age: Int!) {
allPersons(filter: { age_gte: $age } ) {
Expand All @@ -8,20 +8,14 @@ module PersonsOlderThanConfig = [%graphql
|}
];

module PersonsOlderThanQuery =
ReasonApolloHooks.Query.Make(PersonsOlderThanConfig);

[@react.component]
let make = (~age) => {
let getPersonsOlderThan = PersonsOlderThanConfig.make(~age, ());

let (simple, _full) =
PersonsOlderThanQuery.use(~variables=getPersonsOlderThan##variables, ());
ApolloHooks.useQuery(~query=PersonsOlderThanQuery.make(~age, ()), ());

<div>
{switch (simple) {
| ReasonApolloHooks.Query.Loading =>
<p> {React.string("Loading...")} </p>
| Loading => <p> {React.string("Loading...")} </p>
| Data(data) =>
<h3>
{"There are "
Expand All @@ -34,4 +28,4 @@ let make = (~age) => {
| Error(_) => <p> {React.string("Error")} </p>
}}
</div>;
};
};
24 changes: 9 additions & 15 deletions examples/persons/src/FilterByNameCache.re
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* to serialize the parsed data back to its initial format, queries that will be updated manually
* in cache can't use any of those directive, unless you will take care of the serialization yourself.
*/
module PersonsNameFilterConfig = [%graphql
module PersonsNameFilterQuery = [%graphql
{|
query getPersonsWithName($name: String!) {
allPersons(filter: { name: $name } ) {
Expand All @@ -20,7 +20,7 @@ module PersonsNameFilterConfig = [%graphql
|}
];

external cast: Js.Json.t => PersonsNameFilterConfig.t = "%identity";
external cast: Js.Json.t => PersonsNameFilterQuery.t = "%identity";

type person = {
.
Expand All @@ -29,26 +29,23 @@ type person = {
"name": string,
};

module PersonsNameFilterQuery =
ReasonApolloHooks.Query.Make(PersonsNameFilterConfig);

/** example using cache */
module PersonsNameFilterReadQuery =
ApolloClient.ReadQuery(PersonsNameFilterConfig);
ApolloClient.ReadQuery(PersonsNameFilterQuery);

module PersonsNameFilterWriteQuery =
ApolloClient.WriteQuery(PersonsNameFilterConfig);
ApolloClient.WriteQuery(PersonsNameFilterQuery);

let updateFiltered = (person: person, name, filteredPersons: array(person)) =>
person##name === name
? filteredPersons->Belt.Array.concat([|person|])
: filteredPersons->Belt.Array.keep(p => p##id !== person##id);

let updateCache = (client, person, name) => {
let filterByNameQuery = PersonsNameFilterConfig.make(~name, ());
let filterByNameQuery = PersonsNameFilterQuery.make(~name, ());

let readQueryOptions =
ReasonApolloHooks.Utils.toReadQueryOptions(filterByNameQuery);
ApolloHooks.Utils.toReadQueryOptions(filterByNameQuery);

// By default, apollo adds field __typename to the query and will use it
// to normalize data. Parsing the result with Config.parse will remove the field,
Expand Down Expand Up @@ -80,15 +77,12 @@ let updateCache = (client, person, name) => {

[@react.component]
let make = (~name) => {
let getPersonsWithName = PersonsNameFilterConfig.make(~name, ());

let (simple, _full) =
PersonsNameFilterQuery.use(~variables=getPersonsWithName##variables, ());
ApolloHooks.useQuery(~query=PersonsNameFilterQuery.make(~name, ()), ());

<div>
{switch (simple) {
| ReasonApolloHooks.Query.Loading =>
<p> {React.string("Loading...")} </p>
| ApolloHooks.Query.Loading => <p> {React.string("Loading...")} </p>
| Data(data) =>
<h3>
{"There are "
Expand All @@ -101,4 +95,4 @@ let make = (~name) => {
| Error(_) => <p> {React.string("Error")} </p>
}}
</div>;
};
};
Loading