{"id":13528372,"url":"https://github.com/awslabs/aws-mobile-appsync-sdk-js","last_synced_at":"2025-05-13T19:06:33.427Z","repository":{"id":38184876,"uuid":"108162421","full_name":"awslabs/aws-mobile-appsync-sdk-js","owner":"awslabs","description":"JavaScript library files for Offline, Sync, Sigv4. includes support for React Native","archived":false,"fork":false,"pushed_at":"2025-03-18T17:19:33.000Z","size":1285,"stargazers_count":922,"open_issues_count":250,"forks_count":266,"subscribers_count":76,"default_branch":"master","last_synced_at":"2025-05-09T23:39:56.968Z","etag":null,"topics":["appsync","aws","aws-appsync","aws-mobile","graphql","graphql-client","graphql-js","graphql-subscriptions","javascript","js","react"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awslabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-24T17:42:46.000Z","updated_at":"2025-04-27T19:51:49.000Z","dependencies_parsed_at":"2024-01-12T08:48:10.795Z","dependency_job_id":"0a7aebe9-612f-4859-a5ae-e49fb97efd19","html_url":"https://github.com/awslabs/aws-mobile-appsync-sdk-js","commit_stats":{"total_commits":251,"total_committers":51,"mean_commits":4.921568627450981,"dds":0.8007968127490039,"last_synced_commit":"8aa3884309720be9b01edf6042f36ae5ff4368e7"},"previous_names":[],"tags_count":219,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Faws-mobile-appsync-sdk-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Faws-mobile-appsync-sdk-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Faws-mobile-appsync-sdk-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Faws-mobile-appsync-sdk-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awslabs","download_url":"https://codeload.github.com/awslabs/aws-mobile-appsync-sdk-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253656406,"owners_count":21943081,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appsync","aws","aws-appsync","aws-mobile","graphql","graphql-client","graphql-js","graphql-subscriptions","javascript","js","react"],"created_at":"2024-08-01T06:02:28.556Z","updated_at":"2025-05-13T19:06:33.404Z","avatar_url":"https://github.com/awslabs.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Clients","Documentation"],"sub_categories":[],"readme":"# Use AWS AppSync with JavaScript apps \u0026middot; [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/)\n\n![AWS AppSync](https://s3.amazonaws.com/aws-mobile-hub-images/awsappsyncgithub.png)\n\n[AWS AppSync](https://aws.amazon.com/appsync/) is a fully managed service that makes it easy to develop GraphQL APIs by handling the heavy lifting of securely connecting to data sources like AWS DynamoDB, Lambda, and more.\n\nYou can use any HTTP or GraphQL client to connect to a GraphQL API on AppSync.\n\nFor front-end web and mobile development, we recommend using the [AWS Amplify library](https://docs.amplify.aws/lib/graphqlapi/getting-started/q/platform/js/) which is optimized to connect to the AppSync backend.\n\n- For DynamoDB data sources where conflict detection and resolution are enabled on AppSync, use the [DataStore category in the Amplify library](https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js/).\n- For non-DynamoDB data sources in scenarios where you have no offline requirements, use the [API (GraphQL) category in the Amplify library](https://docs.amplify.aws/lib/graphqlapi/getting-started/q/platform/js/).\n- If you want to use the Apollo V3 client, use the Apollo Links in this repository to help with authorization and subscriptions.\n\n**Looking for the AWS AppSync SDK for JavaScript (built on Apollo v2)?** AWS AppSync SDK for JavaScript (V2) is now in Maintenance Mode until June 30th, 2024. This means that we will continue to include updates to ensure compatibility with backend services and security. No new features will be introduced in the AWS AppSync SDK for JavaScript (V2). Please review the [upgrade guide](https://docs.amplify.aws/lib/graphqlapi/upgrade-guide/q/platform/js) for recommended next steps.\n\n## [AWS AppSync](https://aws.amazon.com/appsync/) Links for Apollo V3 (Maintenance mode)\n\nIf you would like to use the [Apollo JavaScript client version 3](https://www.apollographql.com/docs/react/) to connect to your AppSync GraphQL API, this repository (on the current stable branch) provides Apollo links to use the different AppSync authorization modes, and to setup subscriptions over web sockets. Please log questions for this client SDK in this repo and questions for the AppSync service in the [official AWS AppSync forum](https://forums.aws.amazon.com/forum.jspa?forumID=280\u0026start=0) .\n\n![npm](https://img.shields.io/npm/dm/aws-appsync-auth-link.svg)\n![npm](https://img.shields.io/npm/dm/aws-appsync-subscription-link.svg)\n\n| package                       | version                                                                |\n| ----------------------------- | ---------------------------------------------------------------------- |\n| aws-appsync-auth-link         | ![npm](https://img.shields.io/npm/v/aws-appsync-auth-link.svg)         |\n| aws-appsync-subscription-link | ![npm](https://img.shields.io/npm/v/aws-appsync-subscription-link.svg) |\n\n[Example usage of Apollo V3 links](#using-authorization-and-subscription-links-with-apollo-client-v3-no-offline-support)\n\n### React / React Native\n\nFor more documentation on `graphql` operations performed by React Apollo see their [documentation](https://www.apollographql.com/docs/react/).\n\n### Using Authorization and Subscription links with Apollo Client V3 (No offline support)\n\nFor versions of the Apollo client newer than 2.4.6 you can use custom links for Authorization and Subscriptions. Offline support is not available for these newer versions. The packages available are\n`aws-appsync-auth-link` and `aws-appsync-subscription-link`. Below is a sample code snippet that shows how to use it.\n\n```javascript\nimport { createAuthLink } from \"aws-appsync-auth-link\";\nimport { createSubscriptionHandshakeLink } from \"aws-appsync-subscription-link\";\n\nimport {\n  ApolloProvider,\n  ApolloClient,\n  InMemoryCache,\n  HttpLink,\n  ApolloLink,\n} from \"@apollo/client\";\n\nimport appSyncConfig from \"./aws-exports\";\n\n/* The HTTPS endpoint of the AWS AppSync API \n(e.g. *https://aaaaaaaaaaaaaaaaaaaaaaaaaa.appsync-api.us-east-1.amazonaws.com/graphql*). \n[Custom domain names](https://docs.aws.amazon.com/appsync/latest/devguide/custom-domain-name.html) can also be supplied here (e.g. *https://api.yourdomain.com/graphql*). \nCustom domain names can have any format, but must end with `/graphql` \n(see https://graphql.org/learn/serving-over-http/#uris-routes). */\nconst url = appSyncConfig.aws_appsync_graphqlEndpoint;\n\n\nconst region = appSyncConfig.aws_appsync_region;\n\nconst auth = {\n  type: appSyncConfig.aws_appsync_authenticationType,\n  apiKey: appSyncConfig.aws_appsync_apiKey,\n  // jwtToken: async () =\u003e token, // Required when you use Cognito UserPools OR OpenID Connect. token object is obtained previously\n  // credentials: async () =\u003e credentials, // Required when you use IAM-based auth.\n};\n\nconst httpLink = new HttpLink({ uri: url });\n\nconst link = ApolloLink.from([\n  createAuthLink({ url, region, auth }),\n  createSubscriptionHandshakeLink({ url, region, auth }, httpLink),\n]);\n\nconst client = new ApolloClient({\n  link,\n  cache: new InMemoryCache(),\n});\n\nconst ApolloWrapper = ({ children }) =\u003e {\n  return \u003cApolloProvider client={client}\u003e{children}\u003c/ApolloProvider\u003e;\n};\n```\n\n### Queries and Subscriptions using Apollo V3\n\n```js\nimport React, { useState, useEffect } from \"react\";\nimport { gql, useSubscription } from \"@apollo/client\";\nimport { useMutation, useQuery } from \"@apollo/client\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nconst initialState = { name: \"\", description: \"\" };\n\nconst App = () =\u003e {\n\n  const LIST_TODOS = gql`\n    query listTodos {\n      listTodos {\n        items {\n          id\n          name\n          description\n        }\n      }\n    }\n  `;\n\n  const {\n    loading: listLoading,\n    data: listData,\n    error: listError,\n  } = useQuery(LIST_TODOS);\n\n  const CREATE_TODO = gql`\n    mutation createTodo($input: CreateTodoInput!) {\n      createTodo(input: $input) {\n        id\n        name\n        description\n      }\n    }\n  `;\n\n  // https://www.apollographql.com/docs/react/data/mutations/\n  const [addTodoMutateFunction, { error: createError }] =\n    useMutation(CREATE_TODO);\n\n  async function addTodo() {\n    try {\n      addTodoMutateFunction({ variables: { input: { todo } } });\n    } catch (err) {\n      console.log(\"error creating todo:\", err);\n    }\n  }\n\n  const DELETE_TODO = gql`\n    mutation deleteTodo($input: DeleteTodoInput!) {\n      deleteTodo(input: $input) {\n        id\n        name\n        description\n      }\n    }\n  `;\n\n  const [deleteTodoMutateFunction] = useMutation(DELETE_TODO, {\n    refetchQueries: [LIST_TODOS, \"listTodos\"],\n  });\n\n  async function removeTodo(id) {\n    try {\n      deleteTodoMutateFunction({ variables: { input: { id } } });\n    } catch (err) {\n      console.log(\"error deleting todo:\", err);\n    }\n  }\n\n  const CREATE_TODO_SUBSCRIPTION = gql`\n    subscription OnCreateTodo {\n      onCreateTodo {\n        id\n        name\n        description\n      }\n    }\n  `;\n\n  const { data: createSubData, error: createSubError } = useSubscription(\n    CREATE_TODO_SUBSCRIPTION\n  );\n\n  return (\n    // Render TODOs\n  );\n};\n\nexport default App;\n```\n\n\n---\n\n## [AWS AppSync](https://aws.amazon.com/appsync/) JavaScript SDK based on Apollo V2 (Maintenance mode)\n\nThe `aws-appsync` and `aws-appsync-react` packages work with the [Apollo client version 2](https://www.apollographql.com/docs/react/v2) and provide offline capabilities.\n\n**Note:** if you do not have any offline requirements in your app, we recommend using the [Amplify libraries](https://aws-amplify.github.io/).\n\n![npm](https://img.shields.io/npm/dm/aws-appsync.svg)\n\n| package           | version                                                    |\n| ----------------- | ---------------------------------------------------------- |\n| aws-appsync       | ![npm](https://img.shields.io/npm/v/aws-appsync.svg)       |\n| aws-appsync-react | ![npm](https://img.shields.io/npm/v/aws-appsync-react.svg) |\n\n### Installation\n\n#### npm\n\n```sh\nnpm install --save aws-appsync\n```\n\n#### yarn\n\n```sh\nyarn add aws-appsync\n```\n\n#### React Native Compatibility\n\nWhen using this library with React Native, you need to ensure you are using the correct version of the library based on your version of React Native. Take a look at the table below to determine what version to use.\n\n| `aws-appsync` version | Required React Native Version |\n| --------------------- | ----------------------------- |\n| `2.x.x`               | `\u003e= 0.60`                     |\n| `1.x.x`               | `\u003c= 0.59`                     |\n\nIf you are using React Native `0.60` and above, you also need to install `@react-native-community/netinfo` and `@react-native-community/async-storage`:\n\n```sh\nnpm install --save @react-native-community/netinfo@5.9.4 @react-native-community/async-storage\n```\n\nor\n\n```sh\nyarn add @react-native-community/netinfo@5.9.4 @react-native-community/async-storage\n```\n\nIf you are using React Native `0.60+` for iOS, run the following command as an additional step:\n\n```sh\nnpx pod-install\n```  \n\n### Creating a client with AppSync SDK for JavaScript V2 (Maintenance mode)\n\n```js\nimport AWSAppSyncClient from \"aws-appsync\";\nimport AppSyncConfig from \"./aws-exports\";\nimport { ApolloProvider } from \"react-apollo\";\nimport { Rehydrated } from \"aws-appsync-react\"; // this needs to also be installed when working with React\nimport App from \"./App\";\n\nconst client = new AWSAppSyncClient({\n  /* The HTTPS endpoint of the AWS AppSync API \n  (e.g. *https://aaaaaaaaaaaaaaaaaaaaaaaaaa.appsync-api.us-east-1.amazonaws.com/graphql*). \n  [Custom domain names](https://docs.aws.amazon.com/appsync/latest/devguide/custom-domain-name.html) can also be supplied here (e.g. *https://api.yourdomain.com/graphql*). \n  Custom domain names can have any format, but must end with `/graphql` \n  (see https://graphql.org/learn/serving-over-http/#uris-routes). */\n  url: AppSyncConfig.aws_appsync_graphqlEndpoint,\n  region: AppSyncConfig.aws_appsync_region,\n  auth: {\n    type: AppSyncConfig.aws_appsync_authenticationType,\n    apiKey: AppSyncConfig.aws_appsync_apiKey,\n    // jwtToken: async () =\u003e token, // Required when you use Cognito UserPools OR OpenID Connect. Token object is obtained previously\n    // credentials: async () =\u003e credentials, // Required when you use IAM-based auth.\n  },\n});\n\nconst WithProvider = () =\u003e (\n  \u003cApolloProvider client={client}\u003e\n    \u003cRehydrated\u003e\n      \u003cApp /\u003e\n    \u003c/Rehydrated\u003e\n  \u003c/ApolloProvider\u003e\n);\n\nexport default WithProvider;\n```\n\n#### Queries\n\n```js\nimport gql from \"graphql-tag\";\nimport { graphql } from \"react-apollo\";\n\nconst listPosts = gql`\n  query listPosts {\n    listPosts {\n      items {\n        id\n        name\n      }\n    }\n  }\n`;\nclass App extends Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        {this.props.posts.map((post, index) =\u003e (\n          \u003ch2 key={post.id ? post.id : index}\u003e{post.name}\u003c/h2\u003e\n        ))}\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default graphql(listPosts, {\n  options: {\n    fetchPolicy: \"cache-and-network\",\n  },\n  props: (props) =\u003e ({\n    posts: props.data.listPosts ? props.data.listPosts.items : [],\n  }),\n})(App);\n```\n\n#### Mutations \u0026 optimistic UI (with graphqlMutation helper)\n\n```js\nimport gql from \"graphql-tag\";\nimport { graphql, compose } from \"react-apollo\";\nimport { graphqlMutation } from \"aws-appsync-react\";\n\nconst CreatePost = gql`\n  mutation createPost($name: String!) {\n    createPost(input: { name: $name }) {\n      name\n    }\n  }\n`;\n\nclass App extends Component {\n  state = { name: \"\" };\n  onChange = (e) =\u003e {\n    this.setState({ name: e.target.value });\n  };\n  addTodo = () =\u003e this.props.createPost({ name: this.state.name });\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cinput onChange={this.onChange} placeholder=\"Todo name\" /\u003e\n        \u003cbutton onClick={this.addTodo}\u003eAdd Todo\u003c/button\u003e\n        {this.props.posts.map((post, index) =\u003e (\n          \u003ch2 key={post.id ? post.id : index}\u003e{post.name}\u003c/h2\u003e\n        ))}\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default compose(\n  graphql(listPosts, {\n    options: {\n      fetchPolicy: \"cache-and-network\",\n    },\n    props: (props) =\u003e ({\n      posts: props.data.listPosts ? props.data.listPosts.items : [],\n    }),\n  }),\n  graphqlMutation(CreatePost, listPosts, \"Post\")\n)(App);\n```\n\n#### Mutations \u0026 optimistic UI (without graphqlMutation helper)\n\n```js\nimport gql from \"graphql-tag\";\nimport uuidV4 from \"uuid/v4\";\nimport { graphql, compose } from \"react-apollo\";\n\nconst CreatePost = gql`\n  mutation createPost($name: String!) {\n    createPost(input: { name: $name }) {\n      name\n    }\n  }\n`;\n\nclass App extends Component {\n  state = { name: \"\" };\n  onChange = (e) =\u003e {\n    this.setState({ name: e.target.value });\n  };\n  addTodo = () =\u003e this.props.onAdd({ id: uuidV4(), name: this.state.name });\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cinput onChange={this.onChange} placeholder=\"Todo name\" /\u003e\n        \u003cbutton onClick={this.addTodo}\u003eAdd Todo\u003c/button\u003e\n        {this.props.posts.map((post, index) =\u003e (\n          \u003ch2 key={post.id ? post.id : index}\u003e{post.name}\u003c/h2\u003e\n        ))}\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default compose(\n  graphql(listPosts, {\n    options: {\n      fetchPolicy: \"cache-and-network\",\n    },\n    props: (props) =\u003e ({\n      posts: props.data.listPosts ? props.data.listPosts.items : [],\n    }),\n  }),\n  graphql(CreatePost, {\n    options: {\n      update: (dataProxy, { data: { createPost } }) =\u003e {\n        const query = listPosts;\n        const data = dataProxy.readQuery({ query });\n        data.listPosts.items.push(createPost);\n        dataProxy.writeQuery({ query, data });\n      },\n    },\n    props: (props) =\u003e ({\n      onAdd: (post) =\u003e {\n        props.mutate({\n          variables: post,\n          optimisticResponse: () =\u003e ({\n            createPost: { ...post, __typename: \"Post\" },\n          }),\n        });\n      },\n    }),\n  })\n)(App);\n```\n\n#### Subscriptions (with buildSubscription helper)\n\n```js\nimport gql from \"graphql-tag\";\nimport { graphql } from \"react-apollo\";\nimport { buildSubscription } from \"aws-appsync\";\n\nconst listPosts = gql`\n  query listPosts {\n    listPosts {\n      items {\n        id\n        name\n      }\n    }\n  }\n`;\n\nconst PostSubscription = gql`\n  subscription postSubscription {\n    onCreatePost {\n      id\n      name\n    }\n  }\n`;\n\nclass App extends React.Component {\n  componentDidMount() {\n    this.props.data.subscribeToMore(\n      buildSubscription(PostSubscription, listPosts)\n    );\n  }\n  render() {\n    return (\n      \u003cdiv\u003e\n        {this.props.posts.map((post, index) =\u003e (\n          \u003ch2 key={post.id ? post.id : index}\u003e{post.name}\u003c/h2\u003e\n        ))}\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default graphql(listPosts, {\n  options: {\n    fetchPolicy: \"cache-and-network\",\n  },\n  props: (props) =\u003e ({\n    posts: props.data.listPosts ? props.data.listPosts.items : [],\n    data: props.data,\n  }),\n})(App);\n```\n\n#### Subscriptions (without buildSubscription helper)\n\n```js\nimport gql from \"graphql-tag\";\nimport { graphql } from \"react-apollo\";\n\nconst listPosts = gql`\n  query listPosts {\n    listPosts {\n      items {\n        id\n        name\n      }\n    }\n  }\n`;\n\nconst PostSubscription = gql`\n  subscription postSubscription {\n    onCreatePost {\n      id\n      name\n    }\n  }\n`;\n\nclass App extends React.Component {\n  componentDidMount() {\n    this.props.subscribeToNewPosts();\n  }\n  render() {\n    return (\n      \u003cdiv\u003e\n        {this.props.posts.map((post, index) =\u003e (\n          \u003ch2 key={post.id ? post.id : index}\u003e{post.name}\u003c/h2\u003e\n        ))}\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default graphql(listPosts, {\n  options: {\n    fetchPolicy: \"cache-and-network\",\n  },\n  props: (props) =\u003e ({\n    posts: props.data.listPosts ? props.data.listPosts.items : [],\n    subscribeToNewPosts: (params) =\u003e {\n      props.data.subscribeToMore({\n        document: PostSubscription,\n        updateQuery: (\n          prev,\n          {\n            subscriptionData: {\n              data: { onCreatePost },\n            },\n          }\n        ) =\u003e ({\n          ...prev,\n          listPosts: {\n            __typename: \"PostConnection\",\n            items: [\n              onCreatePost,\n              ...prev.listPosts.items.filter(\n                (post) =\u003e post.id !== onCreatePost.id\n              ),\n            ],\n          },\n        }),\n      });\n    },\n  }),\n})(App);\n```\n\n### Complex objects with AWS AppSync SDK for JavaScript (Maintenance mode)\n\nMany times you might want to create logical objects that have more complex data, such as images or videos, as part of their structure. For example, you might create a Person type with a profile picture or a Post type that has an associated image. With AWS AppSync, you can model these as GraphQL types, referred to as complex objects. If any of your mutations have a variable with bucket, key, region, mimeType and localUri fields, the SDK uploads the file to Amazon S3 for you.\n\nFor a complete working example of this feature, see [aws-amplify-graphql](https://github.com/aws-samples/aws-amplify-graphql) on GitHub.\n\nIf you're using AWS Amplify's GraphQL transformer, then configure your resolvers to write to DynamoDB and point at S3 objects when using the `S3Object` type. For example, run the following in an Amplify project:\n\n```bash\namplify add auth        #Select default configuration\namplify add storage     #Select S3 with read/write access\namplify add api         #Select Cognito User Pool for authorization type\n```\n\nWhen prompted, use the following schema:\n\n```graphql\ntype Todo @model {\n  id: ID!\n  name: String!\n  description: String!\n  file: S3Object\n}\ntype S3Object {\n  bucket: String!\n  key: String!\n  region: String!\n}\ninput CreateTodoInput {\n  id: ID\n  name: String!\n  description: String\n  file: S3ObjectInput # This input type will be generated for you\n}\n```\n\nSave and run `amplify push` to deploy changes.\n\nTo use complex objects you need AWS Identity and Access Management credentials for reading and writing to Amazon S3 which `amplify add auth` configures in the default setting along with a Cognito user pool. These can be separate from the other auth credentials you use in your AWS AppSync client. Credentials for complex objects are set using the `complexObjectsCredentials` parameter, which you can use with AWS Amplify and the complex objects feature like so:\n\n```javascript\nconst client = new AWSAppSyncClient({\n    url: ENDPOINT,\n    region: REGION,\n    auth: { ... },   //Can be User Pools or API Key\n    complexObjectsCredentials: () =\u003e Auth.currentCredentials(),\n});\n(async () =\u003e {\n  let file;\n  if (selectedFile) { // selectedFile is the file to be uploaded, typically comes from an \u003cinput type=\"file\" /\u003e\n    const { name, type: mimeType } = selectedFile;\n    const [, , , extension] = /([^.]+)(\\.(\\w+))?$/.exec(name);\n    const bucket = aws_config.aws_user_files_s3_bucket;\n    const region = aws_config.aws_user_files_s3_bucket_region;\n    const visibility = 'private';\n    const { identityId } = await Auth.currentCredentials();\n    const key = `${visibility}/${identityId}/${uuid()}${extension \u0026\u0026 '.'}${extension}`;\n    file = {\n      bucket,\n      key,\n      region,\n      mimeType,\n      localUri: selectedFile,\n    };\n  }\n  const result = await client.mutate({\n    mutation: gql(createTodo),\n    variables: {\n      input: {\n        name: 'Upload file',\n        description: 'Uses complex objects to upload',\n        file: file,\n      }\n    }\n  });\n})();\n```\n\nWhen you run the above mutation, a record will be in a DynamoDB table for your AppSync API as well as the corresponding file in an S3 bucket.\n\n### Offline configuration with AWS AppSync SDK for JavaScript (Maintenance mode)\n\nWhen using the AWS AppSync SDK offline capabilities (e.g. `disableOffline: false`), you can provide configurations for the following:\n\n- Error handling\n- Custom storage engine\n\n#### Error handling\n\nIf a mutation is done while the app was offline, it gets persisted to the platform storage engine. When coming back online, it is sent to the GraphQL endpoint. When a response is returned by the API, the SDK will notify you of the success or error using the callback provided in the `offlineConfig` param as follows:\n\n```javascript\nconst client = new AWSAppSyncClient({\n  url: appSyncConfig.graphqlEndpoint,\n  region: appSyncConfig.region,\n  auth: {\n    type: appSyncConfig.authenticationType,\n    apiKey: appSyncConfig.apiKey,\n  },\n  offlineConfig: {\n    callback: (err, succ) =\u003e {\n      if (err) {\n        const { mutation, variables } = err;\n\n        console.warn(`ERROR for ${mutation}`, err);\n      } else {\n        const { mutation, variables } = succ;\n\n        console.info(`SUCCESS for ${mutation}`, succ);\n      }\n    },\n  },\n});\n```\n\n#### Custom storage engine\n\nYou can use any custom storage engine from the [redux-persist supported engines](https://github.com/rt2zz/redux-persist#storage-engines) list.\n\nConfiguration is done as follows: (localForage shown in the example)\n\n```javascript\nimport * as localForage from \"localforage\";\n\nconst client = new AWSAppSyncClient({\n  url: appSyncConfig.graphqlEndpoint,\n  region: appSyncConfig.region,\n  auth: {\n    type: appSyncConfig.authenticationType,\n    apiKey: appSyncConfig.apiKey,\n  },\n  offlineConfig: {\n    storage: localForage,\n  },\n});\n```\n\n#### Offline helpers\n\nFor detailed documentation about the offline helpers, look at the [API Definition](OFFLINE_HELPERS.md).\n\n### Vue sample with AWS AppSync SDK for JavaScript (Maintenance mode)\n\nFor more documentation on Vue Apollo click [here](https://github.com/Akryum/vue-apollo).\n\n#### main.js\n\n```js\nimport Vue from \"vue\";\nimport App from \"./App\";\nimport router from \"./router\";\n\nimport AWSAppSyncClient from \"aws-appsync\";\nimport VueApollo from \"vue-apollo\";\nimport AppSyncConfig from \"./aws-exports\";\n\nconst config = {\n  url: AppSyncConfig.graphqlEndpoint,\n  region: AppSyncConfig.region,\n  auth: {\n    type: AppSyncConfig.authType,\n    apiKey: AppSyncConfig.apiKey,\n  },\n};\nconst options = {\n  defaultOptions: {\n    watchQuery: {\n      fetchPolicy: \"cache-and-network\",\n    },\n  },\n};\n\nconst client = new AWSAppSyncClient(config, options);\n\nconst appsyncProvider = new VueApollo({\n  defaultClient: client,\n});\n\nVue.use(VueApollo);\n\nnew Vue({\n  el: \"#app\",\n  router,\n  components: { App },\n  provide: appsyncProvider.provide(),\n  template: \"\u003cApp/\u003e\",\n});\n```\n\n#### App.vue\n\n```js\n\u003ctemplate\u003e\n  \u003cdiv id=\"app\" v-if=\"hydrated\"\u003e\n    \u003crouter-view/\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n  name: 'App',\n  data: () =\u003e ({ hydrated: false }),\n  async mounted() {\n    await this.$apollo.provider.defaultClient.hydrated()\n    this.hydrated = true\n  },\n}\n\u003c/script\u003e\n```\n\n#### connected component\n\n```js\nimport gql from \"graphql-tag\";\nimport uuidV4 from \"uuid/v4\";\n\nconst CreateTask = gql`\n  mutation createTask($id: ID!, $name: String!, $completed: Boolean!) {\n    createTask(input: { id: $id, name: $name, completed: $completed }) {\n      id\n      name\n      completed\n    }\n  }\n`;\n\nconst DeleteTask = gql`\n  mutation deleteTask($id: ID!) {\n    deleteTask(input: { id: $id }) {\n      id\n    }\n  }\n`;\n\nconst ListTasks = gql`\n  query listTasks {\n    listTasks {\n      items {\n        id\n        name\n        completed\n      }\n    }\n  }\n`;\n\nconst UpdateTask = gql`\n  mutation updateTask($id: ID!, $name: String!, $completed: Boolean!) {\n    updateTask(input: { id: $id, name: $name, completed: $completed }) {\n      id\n      name\n      completed\n    }\n  }\n`;\n\n// In your component (Examples of queries \u0026 mutations)\nexport default {\n  name: \"Tasks\",\n  methods: {\n    toggleComplete(task) {\n      const updatedTask = {\n        ...task,\n        completed: !task.completed,\n      };\n      this.$apollo\n        .mutate({\n          mutation: UpdateTask,\n          variables: updatedTask,\n          update: (store, { data: { updateTask } }) =\u003e {\n            const data = store.readQuery({ query: ListTasks });\n            const index = data.listTasks.items.findIndex(\n              (item) =\u003e item.id === updateTask.id\n            );\n            data.listTasks.items[index] = updateTask;\n            store.writeQuery({ query: ListTasks, data });\n          },\n          optimisticResponse: {\n            __typename: \"Mutation\",\n            updateTask: {\n              __typename: \"Task\",\n              ...updatedTask,\n            },\n          },\n        })\n        .then((data) =\u003e console.log(data))\n        .catch((error) =\u003e console.error(error));\n    },\n    deleteTask(task) {\n      this.$apollo\n        .mutate({\n          mutation: DeleteTask,\n          variables: {\n            id: task.id,\n          },\n          update: (store, { data: { deleteTask } }) =\u003e {\n            const data = store.readQuery({ query: ListTasks });\n            data.listTasks.items = data.listTasks.items.filter(\n              (task) =\u003e task.id !== deleteTask.id\n            );\n            store.writeQuery({ query: ListTasks, data });\n          },\n          optimisticResponse: {\n            __typename: \"Mutation\",\n            deleteTask: {\n              __typename: \"Task\",\n              ...task,\n            },\n          },\n        })\n        .then((data) =\u003e console.log(data))\n        .catch((error) =\u003e console.error(error));\n    },\n    createTask() {\n      const taskname = this.taskname;\n      if (taskname === \"\") {\n        alert(\"please create a task\");\n        return;\n      }\n      this.taskname = \"\";\n      const id = uuidV4();\n      const task = {\n        name: taskname,\n        id,\n        completed: false,\n      };\n      this.$apollo\n        .mutate({\n          mutation: CreateTask,\n          variables: task,\n          update: (store, { data: { createTask } }) =\u003e {\n            const data = store.readQuery({ query: ListTasks });\n            data.listTasks.items.push(createTask);\n            store.writeQuery({ query: ListTasks, data });\n          },\n          optimisticResponse: {\n            __typename: \"Mutation\",\n            createTask: {\n              __typename: \"Task\",\n              ...task,\n            },\n          },\n        })\n        .then((data) =\u003e console.log(data))\n        .catch((error) =\u003e console.error(\"error!!!: \", error));\n    },\n  },\n  data() {\n    return {\n      taskname: \"\",\n      tasks: [],\n    };\n  },\n  apollo: {\n    tasks: {\n      query: () =\u003e ListTasks,\n      update: (data) =\u003e data.listTasks.items,\n    },\n  },\n};\n```\n\n## Creating an AppSync Project\n\nTo create a new AppSync project, go to \u003chttps://aws.amazon.com/appsync/\u003e.\n\n## License\n\nThis library is licensed under the Apache License 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawslabs%2Faws-mobile-appsync-sdk-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawslabs%2Faws-mobile-appsync-sdk-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawslabs%2Faws-mobile-appsync-sdk-js/lists"}