API update, Readme

This commit is contained in:
Guillaume Chau
2016-09-20 00:50:22 +02:00
parent c8a2baacbb
commit 3c33d8c3fa
3 changed files with 148 additions and 89 deletions
+137 -78
View File
@@ -2,10 +2,12 @@
Integrates [apollo](http://www.apollostack.com/) in your vue components with declarative queries.
[See a simple Apollo server example](https://github.com/Akryum/apollo-server-example)
## Installation
npm install vue-apollo
npm install --save vue-apollo apollo-client
## Usage
@@ -13,11 +15,15 @@ Integrates [apollo](http://www.apollostack.com/) in your vue components with dec
```javascript
import Vue from 'vue';
import ApolloClient from 'apollo-client';
import VueApollo from 'vue-apollo'
import ApolloClient, { createNetworkInterface, addTypename } from './apollo-client';
import VueApollo from 'vue-apollo';
const apolloClient = new ApolloClient({
/* ... */
networkInterface: createNetworkInterface({
uri: 'http://localhost:8080/graphql',
transportBatching: true,
}),
queryTransformer: addTypename,
});
Vue.use(VueApollo, {
@@ -33,28 +39,34 @@ To declare apollo queries in your Vue component, add an `apollo` object :
new Vue({
apollo: {
// Apollo specific options
}
},
});
```
You can access the [apollo-client](http://docs.apollostack.com/apollo-client/index.html) instance with `this.$apollo.client` in all your vue components.
You can access the [apollo-client](http://dev.apollodata.com/core/apollo-client-api.html) instance with `this.$apollo.client` in all your vue components.
### Queries
In the `data` object, add an attribute for each property you want to feed with the result of an Apollo query.
In the `query` object, add an attribute for each property you want to feed with the result of an Apollo query.
#### Simple query
Use `gql` to write your GraphQL queries:
```javascript
import gql from 'graphql-tag';
```
Put the [gql](http://docs.apollostack.com/apollo-client/core.html#gql) query directly as the value:
```javascript
apollo: {
// Non-reactive query
data: {
query: {
// Simple query that will update the 'hello' vue property
hello: gql`{hello}`
}
}
hello: gql`{hello}`,
},
},
```
Don't forget to initialize your property in your vue component:
@@ -63,9 +75,18 @@ Don't forget to initialize your property in your vue component:
data () {
return {
// Initialize your apollo data
hello: ''
}
}
hello: '',
},
},
```
Or with the `ES2015` syntax:
```javascript
data: () => ({
// Initialize your apollo data
hello: '',
}),
```
Server-side, add the corresponding schema and resolver:
@@ -85,12 +106,12 @@ export const resolvers = {
Query: {
hello(root, args, context) {
return "Hello world!";
}
}
},
},
};
```
For more info, visit the [apollo doc](http://docs.apollostack.com/apollo-server/index.html).
For more info, visit the [apollo doc](http://dev.apollodata.com/tools/).
You can then use your property as usual in your vue component:
@@ -113,7 +134,7 @@ You can add variables (read parameters) to your `gql` query by declaring `query`
// Apollo-specific options
apollo: {
// Non-reactive query
data: {
query: {
// Query with parameters
ping: {
// gql query
@@ -122,24 +143,25 @@ apollo: {
}`,
// Static parameters
variables: {
message: 'Meow'
}
}
}
}
message: 'Meow',
},
},
},
},
```
You can use the following apollo options in the object:
You can use the apollo options in the object, like:
- `forceFetch`
- `fragments`
- ...
See the [apollo doc](http://docs.apollostack.com/apollo-client/queries.html#query) for more details.
See the [apollo doc](http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.query) for more details.
For example, you could add the `forceFetch` apollo option like this:
```javascript
apollo: {
data: {
query: {
// Query with parameters
ping: {
query: gql`query PingMessage($message: String!) {
@@ -149,10 +171,10 @@ apollo: {
message: 'Meow'
},
// Additional options here
forceFetch: true
}
}
}
forceFetch: true,
},
},
},
```
Don't forget to initialize your property in your vue component:
@@ -161,9 +183,18 @@ Don't forget to initialize your property in your vue component:
data () {
return {
// Initialize your apollo data
ping: ''
}
}
ping: '',
};
},
```
Or with the `ES2015` syntax:
```javascript
data: () => ({
// Initialize your apollo data
ping: '',
}),
```
Server-side, add the corresponding schema and resolver:
@@ -183,8 +214,8 @@ export const resolvers = {
Query: {
ping(root, { message }, context) {
return `Answering ${message}`;
}
}
},
},
};
```
@@ -209,7 +240,7 @@ Use a function instead to make the parameters reactive with vue properties:
// Apollo-specific options
apollo: {
// Non-reactive query
data: {
query: {
// Query with parameters
ping: {
query: gql`query PingMessage($message: String!) {
@@ -219,12 +250,12 @@ apollo: {
variables() {
// Use vue reactive properties here
return {
message: this.pingInput
}
}
}
}
}
message: this.pingInput,
};
},
},
},
},
```
This will re-fetch the query each time a parameter changes, for example:
@@ -255,7 +286,7 @@ These are the available advanced options you can use:
// Apollo-specific options
apollo: {
// Non-reactive query
data: {
query: {
// Advanced query with parameters
// The 'variables' method is watched by vue
pingMessage: {
@@ -266,8 +297,8 @@ apollo: {
variables() {
// Use vue reactive properties here
return {
message: this.pingInput
}
message: this.pingInput,
};
},
// We use a custom update callback because
// the field names don't match
@@ -298,13 +329,13 @@ apollo: {
watchLoading(isLoading, countModifier) {
// isLoading is a boolean
// countModifier is either 1 or -1
}
}
}
}
},
},
},
},
```
If you use ES2015, you can also write the `update` like this:
If you use `ES2015`, you can also write the `update` like this:
```javascript
update: data => data.ping
@@ -312,29 +343,27 @@ update: data => data.ping
### Reactive Queries
*For now, the reactivity in apollo is quite limited, since you can only do polling.*
For more info, see the [apollo doc](http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.watchQuery).
For more info, see the [apollo doc](http://docs.apollostack.com/apollo-client/core.html#watchQuery).
Add your queries in a `watch` object instead of `data`:
Add your queries in a `watchQuery` object instead of `data`:
```javascript
// Apollo-specific options
apollo: {
// Reactive query
watch: {
watchQuery: {
// 'tags' data property on vue instance
tags: {
query: gql`{
query: gql`query tagList {
tags {
id,
label
}
}`,
pollInterval: 300 // ms
}
}
}
pollInterval: 300, // ms
},
},
},
```
You can use the apollo options, for example:
@@ -342,8 +371,9 @@ You can use the apollo options, for example:
- `returnPartialData`
- `pollInterval`
- `fragments`
- ...
See the [apollo doc](http://docs.apollostack.com/apollo-client/queries.html#watchQuery) for more details.
See the [apollo doc](http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.watchQuery) for more details.
You can also use the advanced options detailed above, like `result` or `watchLoading`.
@@ -378,7 +408,7 @@ for (let i = 0; i < 42; i++) {
function addTag(label) {
let t = {
id: id++,
label
label,
};
tags.push(t);
return t;
@@ -388,41 +418,70 @@ export const resolvers = {
Query: {
tags(root, args, context) {
return tags;
}
}
},
},
};
```
### Mutations
Mutations are queries that changes your data state on your apollo server. For more info, visit the [apollo doc](http://docs.apollostack.com/apollo-client/core.html#Mutations).
Mutations are queries that changes your data state on your apollo server. For more info, visit the [apollo doc](http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\.mutate).
```javascript
methods: {
addTag() {
// Mutate the tags data
// You can also use this.$apollo.client.mutate
// We save the user input in case of an error
const newTag = this.newTag;
// We clear it early to give the UI a snappy feel
this.newTag = '';
// Call to the graphql mutation
this.$apollo.mutate({
mutation: gql`mutation AddTag($label: String!) {
// Query
mutation: gql`mutation ($label: String!) {
addTag(label: $label) {
id,
id
label
}
}`,
// Parameters
variables: {
label: this.tagLabel
}
label: newTag,
},
// Update the cache with the result
// 'tagList' is the name of the query declared before
// that will be updated with the optimistic response
// and the result of the mutation
updateQueries: {
tagList: (previousQueryResult, { mutationResult }) => {
// We incorporate any received result (either optimistic or real)
// into the 'tagList' query we set up earlier
return {
tags: [...previousQueryResult.tags, mutationResult.data.addTag],
};
},
},
// Optimistic UI
// Will be treated as a 'fake' result as soon as the request is made
// so that the UI can react quickly and the user be happy
optimisticResponse: {
__typename: 'Mutation',
addTag: {
__typename: 'Tag',
id: -1,
label: newTag,
},
},
}).then((data) => {
// Result
console.log(data);
this.tagLabel = '';
}).catch((error) => {
// Error
console.error(error);
// We restore the initial user input
this.newTag = newTag;
});
}
}
},
},
```
Server-side:
@@ -461,7 +520,7 @@ for (let i = 0; i < 42; i++) {
function addTag(label) {
let t = {
id: id++,
label
label,
};
tags.push(t);
return t;
@@ -471,14 +530,14 @@ export const resolvers = {
Query: {
tags(root, args, context) {
return tags;
}
},
},
Mutation: {
addTag(root, { label }, context) {
console.log(`adding tag '${label}'`);
return addTag(label);
}
}
},
},
};
```
+8 -8
View File
@@ -1,4 +1,4 @@
import _ from 'lodash';
import omit from 'lodash.omit';
let apolloClient = null;
@@ -59,7 +59,7 @@ class DollarApollo {
}
function generateApolloOptions(variables) {
const apolloOptions = _.omit(options, [
const apolloOptions = omit(options, [
'variables',
'watch',
'update',
@@ -187,16 +187,16 @@ function prepare() {
if (apollo) {
// One-time queries with $query(), called each time a Vue dependency is updated (using $watch)
if (apollo.data) {
for (let key in apollo.data) {
this.$apollo.option(key, apollo.data[key], false);
if (apollo.query) {
for (let key in apollo.query) {
this.$apollo.option(key, apollo.query[key], false);
}
}
// Auto updating queries with $watchQuery(), re-called each time a Vue dependency is updated (using $watch)
if (apollo.watch) {
for (let key in apollo.watch) {
this.$apollo.option(key, apollo.watch[key], true);
if (apollo.watchQuery) {
for (let key in apollo.watchQuery) {
this.$apollo.option(key, apollo.watchQuery[key], true);
}
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "vue-apollo",
"version": "1.0.0",
"version": "1.0.0-beta1",
"description": "Vue apollo integration",
"main": "index.js",
"scripts": {
@@ -21,7 +21,7 @@
"url": "https://github.com/Akryum/vue-apollo/issues"
},
"homepage": "https://github.com/Akryum/vue-apollo#readme",
"dependencies": {
"lodash": "^4.15.0"
"peerDependencies": {
"apollo-client": "^0.4.15"
}
}