1.0.0 • Published 6 years ago
ama-aws-appsync v1.0.0
AWS AppSync JavaScript SDK
This SDK can be used with the Apollo JavaScript client found here.
package | version |
---|---|
ama-aws-appsync | |
aws-appsync-react |
Installation
npm
npm install --save ama-aws-appsync
yarn
yarn add ama-aws-appsync
Linking
This package relies on rn-fetch-blob
to work with the filesystem. This dependency must be linked in your React Native build.
yarn run react-native link rn-fetch-blob
Usage
Vue
Angular
Creating a new AWS AppSync API
License
React / React Native
For more documentation on graphql
operations performed by React Apollo click here.
Creating a client
import AWSAppSyncClient from 'aws-appsync'
import AppSyncConfig from './aws-exports'
import { ApolloProvider } from 'react-apollo'
import { Rehydrated } from 'aws-appsync-react' // this needs to also be installed when working with React
import App from './App'
const client = new AWSAppSyncClient({
url: AppSyncConfig.graphqlEndpoint,
region: AppSyncConfig.region,
auth: {
type: AppSyncConfig.authenticationType,
apiKey: AppSyncConfig.apiKey,
// jwtToken: async () => token, // Required when you use Cognito UserPools OR OpenID Connect. token object is obtained previously
}
})
const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
)
export default WithProvider
Queries
import gql from 'graphql-tag'
import { graphql } from 'react-apollo'
const listPosts = gql`
query listPosts {
listPosts {
items {
id
name
}
}
}
`
class App extends Component {
render() {
return (
<div>
{
this.props.posts.map((post, index) => (
<h2 key={index}>{post.name}</h2>
))
}
</div>
)
}
}
export default graphql(listPosts, {
options: {
fetchPolicy: 'cache-and-network'
},
props: props => ({
posts: props.data.listPosts ? props.data.listPosts.items : []
})
})(App)
Mutations & optimistic UI (with graphqlMutation helper)
import gql from 'graphql-tag'
import { graphql, compose } from 'react-apollo'
import { graphqlMutation } from 'aws-appsync-react'
const CreatePost = gql`
mutation createPost($name: String!) {
createPost(input: {
name: $name
}) {
name
}
}
`
class App extends Component {
state = { name: '' }
onChange = (e) => { this.setState({ name: e.target.value }) }
addTodo = () => this.props.createPost({ name: this.state.name })
render() {
return (
<div>
<input onChange={this.onChange} placeholder='Todo name' />
<button onClick={this.addTodo}>Add Todo</button>
{
this.props.posts.map((post, index) => (
<h2 key={index}>{post.name}</h2>
))
}
</div>
)
}
}
export default compose(
graphql(listPosts, {
options: {
fetchPolicy: 'cache-and-network'
},
props: props => ({
posts: props.data.listPosts ? props.data.listPosts.items : []
})
}),
graphqlMutation(CreatePost, listPosts, 'Post')
)(App)
Mutations & optimistic UI (without graphqlMutation helper)
import gql from 'graphql-tag'
import uuidV4 from 'uuid/v4'
import { graphql, compose } from 'react-apollo'
const CreatePost = gql`
mutation createPost($name: String!) {
createPost(input: {
name: $name
}) {
name
}
}
`
class App extends Component {
state = { name: '' }
onChange = (e) => { this.setState({ name: e.target.value }) }
addTodo = () => this.props.onAdd({ id: uuidV4(), name: this.state.name })
render() {
return (
<div>
<input onChange={this.onChange} placeholder='Todo name' />
<button onClick={this.addTodo}>Add Todo</button>
{
this.props.posts.map((post, index) => (
<h2 key={index}>{post.name}</h2>
))
}
</div>
)
}
}
export default compose(
graphql(listPosts, {
options: {
fetchPolicy: 'cache-and-network'
},
props: props => ({
posts: props.data.listPosts ? props.data.listPosts.items : []
})
}),
graphql(CreatePost, {
options: {
update: (dataProxy, { data: { createPost } }) => {
const query = listPosts
const data = dataProxy.readQuery({ query })
data.listPosts.items.push(createPost)
dataProxy.writeQuery({ query, data })
}
},
props: (props) => ({
onAdd: (post) => {
props.mutate({
variables: post,
optimisticResponse: () => ({
createPost: { ...post, __typename: 'Post' }
}),
})
}
}),
})
)(App)
Subscriptions (with buildSubscription helper)
import gql from 'graphql-tag'
import { graphql } from 'react-apollo'
import { buildSubscription } from 'aws-appsync'
const listPosts = gql`
query listPosts {
listPosts {
items {
id
name
}
}
}
`
const PostSubscription = gql`
subscription postSubscription {
onCreatePost {
id
name
}
}
`
class App extends React.Component {
componentDidMount() {
this.props.data.subscribeToMore(
buildSubscription(PostSubscription, listPosts)
)
}
render() {
return (
<div>
{
this.props.posts.map((post, index) => (
<h2 key={index}>{post.name}</h2>
))
}
</div>
)
}
}
export default graphql(listPosts, {
options: {
fetchPolicy: 'cache-and-network'
},
props: props => ({
posts: props.data.listPosts ? props.data.listPosts.items : [],
data: props.data
})
})(App)
Subscriptions (without buildSubscription helper)
import gql from 'graphql-tag'
import { graphql } from 'react-apollo'
const listPosts = gql`
query listPosts {
listPosts {
items {
id
name
}
}
}
`
const PostSubscription = gql`
subscription postSubscription {
onCreatePost {
id
name
}
}
`
class App extends React.Component {
componentDidMount() {
this.props.subscribeToNewPosts()
}
render() {
return (
<div>
{
this.props.posts.map((post, index) => (
<h2 key={index}>{post.name}</h2>
))
}
</div>
)
}
}
export default graphql(listPosts, {
options: {
fetchPolicy: 'cache-and-network'
},
props: props => ({
posts: props.data.listPosts ? props.data.listPosts.items : [],
subscribeToNewPosts: params => {
props.data.subscribeToMore({
document: PostSubscription,
updateQuery: (prev, { subscriptionData: { data : { onCreatePost } } }) => ({
...prev,
listPosts: { __typename: 'PostConnection', items: [onCreatePost, ...prev.listPosts.items.filter(post => post.id !== onCreatePost.id)] }
})
})
},
})
})(App)
Offline helpers
For detailed documentation about the offline helpers, look at the API Definition.
Vue
For more documentation on Vue Apollo click here.
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import AWSAppSyncClient from 'aws-appsync'
import VueApollo from 'vue-apollo'
import AppSyncConfig from './aws-exports'
const config = {
url: AppSyncConfig.graphqlEndpoint,
region: AppSyncConfig.region,
auth: {
type: AppSyncConfig.authType,
apiKey: AppSyncConfig.apiKey,
}
}
const options = {
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-and-network',
}
}
}
const client = new AWSAppSyncClient(config, options)
const appsyncProvider = new VueApollo({
defaultClient: client
})
Vue.use(VueApollo)
new Vue({
el: '#app',
router,
components: { App },
provide: appsyncProvider.provide(),
template: '<App/>'
})
App.vue
<template>
<div id="app" v-if="hydrated">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data: () => ({ hydrated: false }),
async mounted() {
await this.$apollo.provider.defaultClient.hydrated()
this.hydrated = true
},
}
</script>
connected component
import gql from 'graphql-tag'
import uuidV4 from 'uuid/v4'
const CreateTask = gql`
mutation createTask($id: ID!, $name: String!, $completed: Boolean!) {
createTask(
input: {
id: $id, name: $name, completed: $completed
}
) {
id
name
completed
}
}
`
const DeleteTask = gql`
mutation deleteTask($id: ID!) {
deleteTask(
input: {
id: $id
}
) {
id
}
}
`
const ListTasks = gql`
query listTasks {
listTasks {
items {
id
name
completed
}
}
}
`
const UpdateTask = gql`
mutation updateTask($id: ID!, $name: String!, $completed: Boolean!) {
updateTask(
input: {
id: $id
name: $name
completed: $completed
}
) {
id
name
completed
}
}
`
// In your component (Examples of queries & mutations)
export default {
name: 'Tasks',
methods: {
toggleComplete(task) {
const updatedTask = {
...task,
completed: !task.completed
}
this.$apollo.mutate({
mutation: UpdateTask,
variables: updatedTask,
update: (store, { data: { updateTask } }) => {
const data = store.readQuery({ query: ListTasks })
const index = data.listTasks.items.findIndex(item => item.id === updateTask.id)
data.listTasks.items[index] = updateTask
store.writeQuery({ query: ListTasks, data })
},
optimisticResponse: {
__typename: 'Mutation',
updateTask: {
__typename: 'Task',
...updatedTask
}
},
})
.then(data => console.log(data))
.catch(error => console.error(error))
},
deleteTask(task) {
this.$apollo.mutate({
mutation: DeleteTask,
variables: {
id: task.id
},
update: (store, { data: { deleteTask } }) => {
const data = store.readQuery({ query: ListTasks })
data.listTasks.items = data.listTasks.items.filter(task => task.id !== deleteTask.id)
store.writeQuery({ query: ListTasks, data })
},
optimisticResponse: {
__typename: 'Mutation',
deleteTask: {
__typename: 'Task',
...task
}
},
})
.then(data => console.log(data))
.catch(error => console.error(error))
},
createTask() {
const taskname = this.taskname
if ((taskname) === '') {
alert('please create a task')
return
}
this.taskname = ''
const id = uuidV4()
const task = {
name: taskname,
id,
completed: false
}
this.$apollo.mutate({
mutation: CreateTask,
variables: task,
update: (store, { data: { createTask } }) => {
const data = store.readQuery({ query: ListTasks })
data.listTasks.items.push(createTask)
store.writeQuery({ query: ListTasks, data })
},
optimisticResponse: {
__typename: 'Mutation',
createTask: {
__typename: 'Task',
...task
}
},
})
.then(data => console.log(data))
.catch(error => console.error("error!!!: ", error))
},
},
data () {
return {
taskname: '',
tasks: []
}
},
apollo: {
tasks: {
query: () => ListTasks,
update: data => data.listTasks.items
}
},
}
Angular / Ionic examples coming soon
Creating an AppSync Project
To create a new AppSync project, go to https://aws.amazon.com/appsync/.
License
This library is licensed under the Amazon Software License.