{"id":20664020,"url":"https://github.com/flutterando/hasura_connect","last_synced_at":"2025-04-05T09:10:31.722Z","repository":{"id":35053871,"uuid":"201123877","full_name":"Flutterando/hasura_connect","owner":"Flutterando","description":"Connect your Flutter/Dart apps to Hasura simply.","archived":false,"fork":false,"pushed_at":"2024-06-17T17:19:44.000Z","size":2035,"stargazers_count":204,"open_issues_count":23,"forks_count":62,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-06-25T15:44:07.080Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/hasura_connect","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flutterando.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-07T20:34:02.000Z","updated_at":"2024-08-03T17:02:49.216Z","dependencies_parsed_at":"2024-06-17T19:16:03.598Z","dependency_job_id":"981c7483-ae8b-4f6a-b8c3-5873bf49a324","html_url":"https://github.com/Flutterando/hasura_connect","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fhasura_connect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fhasura_connect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fhasura_connect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fhasura_connect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flutterando","download_url":"https://codeload.github.com/Flutterando/hasura_connect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312085,"owners_count":20918344,"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":[],"created_at":"2024-11-16T19:21:43.249Z","updated_at":"2025-04-05T09:10:31.676Z","avatar_url":"https://github.com/Flutterando.png","language":"Dart","readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\n\u003ch1 align=\"center\"\u003e Hasura Connect  - Connect your Flutter/Dart apps to Hasura simply.\u003c/h1\u003e\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/othneildrew/Best-README-Template\"\u003e\n    \u003cimg src=\"images/logo.png\" alt=\"Logo\" width=\"180\"\u003e\n  \u003c/a\u003e\n\u003cbr\u003e\u003c/br\u003e\n  \u003cp align=\"center\"\u003e\n    The hasura_connect is designed to facilitate Hasura's integration with Flutter applications.\n    \u003cbr /\u003e\n    \u003c!-- \u003ca href=\"https://github.com/othneildrew/Best-README-Template\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e --\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003c!-- \u003ca href=\"https://github.com/othneildrew/Best-README-Template\"\u003eView Demo\u003c/a\u003e \n    ·--\u003e\n    \u003ca href=\"https://github.com/othneildrew/Best-README-Template/issues\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/othneildrew/Best-README-Template/issues\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/p\u003e\n\n\u003cbr\u003e\n\n\u003c!--  SHIELDS  ----\u003e\n\n[![License](https://img.shields.io/github/license/flutterando/hasura_connect?style=plastic)](https://github.com/Flutterando/hasura_connect/blob/master/LICENSE)\n[![Pub Points](https://img.shields.io/pub/points/hasura_connect?label=pub%20points\u0026style=plastic)](https://pub.dev/packages/hasura_connect/score)\n[![Contributors](https://img.shields.io/github/contributors/flutterando/hasura_connect?style=plastic)](https://github.com/Flutterando/hasura_connect/graphs/contributors)\n[![Forks](https://img.shields.io/github/forks/flutterando/hasura_connect?color=yellowgreen\u0026logo=github\u0026style=plastic)](https://github.com/Flutterando/hasura_connect/graphs/contributors)\n\n[![Pub Publisher](https://img.shields.io/pub/publisher/hasura_connect?style=plastic)](https://pub.dev/publishers/flutterando.com.br/packages)\n[![Flutterando Youtube](https://img.shields.io/youtube/channel/subscribers/UCplT2lzN6MHlVHHLt6so39A?color=blue\u0026label=Flutterando\u0026logo=YouTube\u0026logoColor=red\u0026style=plastic)](https://www.youtube.com/flutterando)\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\n      \u003ca href=\"#about-the-project\"\u003eAbout The Project\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#sponsors\"\u003eSponsors\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\n      \u003ca href=\"#getting-started\"\u003eGetting Started\u003c/a\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n\u003cbr\u003e\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n## About The Project\n\n\u003cbr\u003e\n\u003c!-- \u003cCenter\u003e\n\u003cimg src=\"images/Example-uno.png\" alt=\"Uno PNG\" width=\"400\"\u003e\n\u003c/Center\u003e --\u003e\n\n\u003cbr\u003e\n\nThe hasura_connect is designed to facilitate Hasura's integration with Flutter applications, leveraging the full power of Graphql. \n\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- SPONSORS --\u003e\n## Sponsors\n\n\u003ca href=\"https://fteam.dev\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/Flutterando/hasura_connect/master/images/sponsor-logo.png\" alt=\"Logo\" width=\"180\"\u003e\n  \u003c/a\u003e\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\u003cbr\u003e\n\n\n\u003c!-- GETTING STARTED --\u003e\n## Getting Started\n\nTo install Hasura Connect in your project you can follow the instructions below:\n\n\na) Add in your pubspec.yaml:\n   ```sh\n   dependencies:\n   hasura_connect: \u003clast-version\u003e\n   ```\n   \nb)    or use slidy:\n   ```sh\n   slidy install hasura_connect\n   ```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- USAGE EXAMPLES --\u003e\n## How To Use\n\nA simple usage example:\n\n```dart\n//import\nimport 'package:hasura_connect/hasura_connect.dart';\n\nString url = 'http://localhost:8080/v1/graphql';\nHasuraConnect hasuraConnect = HasuraConnect(url);\n```\nYou can encapsulate this instance into a BLoC class or directly into a Provider.\n\nCreate a document with Query:\n\n```dart\n//document\n  String docQuery = \"\"\"\n  query {\n    authors {\n        id\n        email\n        name\n      }\n  }\n\"\"\";\n``` \n\nNow just add the document to the \"query\" method of the HasuraConnect instance.\n\n```dart\n  //get query\nvar r = await hasuraConnect.query(docQuery);\n\n//OR USE MUTATION\nvar r = await hasuraConnect.mutation(docQuery);\n``` \n## Subscriptions\n\nSubscriptions will notify you each time you have a change to the searched items. Use the \"hasuraConnect.subscription\" method to receive a stream.\n\n```dart\nSnapshot snapshot = await hasuraConnect.subscription(docSubscription);\n  snapshot.listen((data) {\n    print(data);\n  }).onError((err) {\n    print(err);\n  });\n``` \n\n## Using variables\n\nVariables maintain the integrity of Querys, see an example:\n\n```dart\nString docSubscription = \"\"\"\n  subscription algumaCoisa($limit:Int!){\n    users(limit: $limit, order_by: {user_id: desc}) {\n      id\n      email\n      name\n    }\n  }\n\"\"\";\n\nSnapshot snapshot = await hasuraConnect.subscription(docSubscription, variables: {\"limit\": 10});\n\n//change values of variables for PAGINATIONS\nsnapshot.changeVariable({\"limit\": 20});\n``` \n\n## INTERCEPTORS\n\nThis is a good strategy to control the flow of requests. With that we can create interceptors for logs or cache for example. The community has already provided some interceptors for caching. Interceptors are highly customizable.\n\n* \u003ca href=\"https://pub.dev/packages/hive_cache_interceptor\"\u003ehive_cache_interceptor\u003c/a\u003e\n* \u003ca href=\"https://pub.dev/packages/shared_preferences_cache_interceptor\"\u003eshared_preferences_cache_interceptor\u003c/a\u003e\n* \u003ca href=\"https://pub.dev/packages/hasura_cache_interceptor\"\u003ehasura_cache_interceptor\u003c/a\u003e\n\n \u003ca href=\"https://docs.hasura.io/1.0/graphql/manual/auth/index.html\"\u003eView Hasura's official Authorization documentation\u003c/a\u003e.\n\n ```dart\nclass TokenInterceptor extends Interceptor {\n  final FirebaseAuth auth;\n  TokenInterceptor(this.auth);\n\n  @override\n  Future\u003cvoid\u003e onConnected(HasuraConnect connect) {}\n\n  @override\n  Future\u003cvoid\u003e onDisconnected() {}\n\n  @override\n  Future onError(HasuraError request) async {\n    return request;\n  }\n\n  @override\n  Future\u003cRequest\u003e onRequest(Request request) async {\n    var user = await auth.currentUser();\n    var token = await user.getIdToken(refresh: true);\n    if (token != null) {\n      try {\n        request.headers[\"Authorization\"] = \"Bearer ${token.token}\";\n        return request;\n      } catch (e) {\n        return null;\n      }\n    } else {\n      Modular.to.pushReplacementNamed(\"/login\");\n    }\n  }\n\n  @override\n  Future onResponse(Response data) async {\n    return data;\n  }\n\n  @override\n  Future\u003cvoid\u003e onSubscription(Request request, Snapshot snapshot) {}\n\n  @override\n  Future\u003cvoid\u003e onTryAgain(HasuraConnect connect) {}\n}\n``` \nOr:\n\n```dart\nclass TokenInterceptor extends InterceptorBase {\n  final FirebaseAuth auth;\n  TokenInterceptor(this.auth);\n\n  @override\n  Future\u003cRequest\u003e onRequest(Request request) async {\n    var user = await auth.currentUser();\n    var token = await user.getIdToken(refresh: true);\n    if (token != null) {\n      try {\n        request.headers[\"Authorization\"] = \"Bearer ${token.token}\";\n        return request;\n      } catch (e) {\n        return null;\n      }\n    } else {\n      Modular.to.pushReplacementNamed(\"/login\");\n    }\n  }\n}\n``` \n## INTERCEPTOR\n\nNow you can intercept all requests, erros, subscritions.... all states of your hasura_connect connection.\n\n* onConnected\n* onDisconnected\n* onError\n* onRequest\n* onResponse\n* onSubscription\n* onTryAgain\n\n## CACHE OFFLINE\n\nNow you will need to create a Interceptor or use a Cache Interceptor Package made to help you like: \u003ca href=\"https://pub.dev/packages/hasura_cache_interceptor\"\u003eInMemory\u003c/a\u003e, \u003ca href=\"https://pub.dev/packages/hive_cache_interceptor\"\u003e Hive\u003c/a\u003e or \u003ca href=\"https://pub.dev/packages/shared_preferences_cache_interceptor\"\u003eSharedPreference\u003c/a\u003e \n\n```dart\n//In Memory\nimport 'package:hasura_cache_interceptor/hasura_hive_cache_interceptor.dart';\n\nfinal storage = MemoryStorageService();\nfinal cacheInterceptor = CacheInterceptor(storage);\nfinal hasura = HasuraConnect(\n  \"\u003cyour hasura url\u003e\",\n  interceptors: [cacheInterceptor],\n  httpClient: httpClient,\n)\n``` \n\n```dart\n//Hive\nimport 'package:hasura_connect/hasura_connect.dart';\nimport 'package:hasura_hive_cache_interceptor/hasura_hive_cache_interceptor.dart';\n\nfinal cacheInterceptor = HiveCacheInterceptor(\"\u003cyour box name\u003e (optional)\");\nfinal hasura = HasuraConnect(\n  \"\u003cyour hasura url\u003e\",\n  interceptors: [cacheInterceptor],\n  httpClient: httpClient,\n)\n```\n\n```dart\n//Shared Preference\nimport 'package:hasura_connect/hasura_connect.dart';\nimport 'package:shared_preferences_cache_interceptor/shared_preferences_cache_interceptor.dart';\n\nfinal cacheInterceptor = SharedPreferencesCacheInterceptor();\nfinal hasura = HasuraConnect(\n  \"\u003cyour hasura url\u003e\",\n  interceptors: [cacheInterceptor],\n  httpClient: httpClient,\n)\n``` \n\n## Dispose\n\nHasuraConnect provides a dispose() method for use in Provider or BlocProvider. Subscription will start only when someone is listening, and when all listeners are closed HasuraConnect automatically disconnects.\n\nTherefore, we only connect to Hasura when we are actually using it;\n\n_For more examples, please refer to the 🚧 [Documentation](https://example.com) - Currently being updated 🚧 .\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n## Common Errors\n\n- Query data returned not decoded to utf-8. \n\nFix:\n\n```dart\nimport 'dart:convert';\n\nextension Utf8convert on String {\n  String  _utf8convert() {\n    List\u003cint\u003e bytes = this.toString().codeUnits;\n    return utf8.decode(bytes);\n  }\n  String get utf8convert =\u003e _utf8convert();\n}\n``` \n\n\n\n\u003c!-- ROADMAP --\u003e\n## Features\n\n- ✅ Queries\n- ✅ Mutations\n- ✅ Subscriptions\n- ✅ Change Variable in Subscriptions\n- ✅ Auto-Reconnect\n- ✅ Dynamic JWT Token\n- ✅ bloc_pattern Integration\n- ✅ Provider Integration\n- ✅ Variables\n- ✅ Cache Subscription\n- ✅ Cache Mutation\n- ✅ Cache Query\n\nRight now this package has concluded all his intended features. If you have any suggestions or find something to report, see below how to contribute to it.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- CONTRIBUTING --\u003e\n## Contributing\n\n🚧 [Contributing Guidelines](https://github.com/angular/angular/blob/main/CONTRIBUTING.md) - Currently being updated 🚧\n\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the appropriate tag. \nDon't forget to give the project a star! Thanks again!\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\nRemember to include a tag, and to follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) and [Semantic Versioning](https://semver.org/) when uploading your commit and/or creating the issue. \n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- LICENSE --\u003e\n## License\n\nDistributed under the MIT License. See `LICENSE.txt` for more information.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- CONTACT --\u003e\n## Contact\n\nFlutterando Community\n- [Discord](https://discord.gg/qNBDHNARja)\n- [Telegram](https://t.me/flutterando)\n- [Website](https://www.flutterando.com.br/)\n- [Youtube Channel](https://www.youtube.com.br/flutterando)\n- [Other useful links](https://linktr.ee/flutterando)\n\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- ACKNOWLEDGMENTS --\u003e\n## Contributors \n\n\u003ca href=\"https://github.com/flutterando/hasura_connect/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=flutterando/hasura_connect\" /\u003e\n\u003c/a\u003e\n\u003c!-- Bot para Lista de contribuidores - https://allcontributors.org/  --\u003e\n\u003c!-- Opção (utilizada no momento): https://contrib.rocks/preview?repo=flutterando%2Fasuka --\u003e\n\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- ACKNOWLEDGMENTS --\u003e\n## Maintaned by\n\n---\n\n\u003cbr\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.flutterando.com.br\"\u003e\n    \u003cimg width=\"110px\" src=\"https://raw.githubusercontent.com/Flutterando/hasura_connect/master/images/logo-flutterando.png\"\u003e\n  \u003c/a\u003e\n  \u003cp align=\"center\"\u003e\n    Built and maintained by \u003ca href=\"https://www.flutterando.com.br\"\u003eFlutterando\u003c/a\u003e.\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\n\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\u003c!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --\u003e\n\n\u003c!-- [Choose an Open Source License](https://choosealicense.com)\n[GitHub Emoji Cheat Sheet](https://www.webpagefx.com/tools/emoji-cheat-sheet)\n[Malven's Flexbox Cheatsheet](https://flexbox.malven.co/)\n[Malven's Grid Cheatsheet](https://grid.malven.co/)\n[Img Shields](https://shields.io)\n[GitHub Pages](https://pages.github.com)\n[Font Awesome](https://fontawesome.com)\n[React Icons](https://react-icons.github.io/react-icons/search) \n\n[contributors-shield]: https://img.shields.io/github/contributors/othneildrew/Best-README-Template.svg?style=for-the-badge\n[contributors-url]: https://github.com/othneildrew/Best-README-Template/graphs/contributors\n[forks-shield]: https://img.shields.io/github/forks/othneildrew/Best-README-Template.svg?style=for-the-badge\n[forks-url]: https://github.com/othneildrew/Best-README-Template/network/members\n[stars-shield]: https://img.shields.io/github/stars/othneildrew/Best-README-Template.svg?style=for-the-badge\n[stars-url]: https://github.com/othneildrew/Best-README-Template/stargazers\n[issues-shield]: https://img.shields.io/github/issues/othneildrew/Best-README-Template.svg?style=for-the-badge\n[issues-url]: https://github.com/othneildrew/Best-README-Template/issues\n[license-shield]: https://img.shields.io/github/license/othneildrew/Best-README-Template.svg?style=for-the-badge\n[license-url]: https://github.com/othneildrew/Best-README-Template/blob/master/LICENSE.txt\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge\u0026logo=linkedin\u0026colorB=555\n[linkedin-url]: https://linkedin.com/in/othneildrew\n[product-screenshot]: images/screenshot.png\n[Next.js]: https://img.shields.io/badge/next.js-000000?style=for-the-badge\u0026logo=nextdotjs\u0026logoColor=white\n[Next-url]: https://nextjs.org/\n[React.js]: https://img.shields.io/badge/React-20232A?style=for-the-badge\u0026logo=react\u0026logoColor=61DAFB\n[React-url]: https://reactjs.org/\n[Vue.js]: https://img.shields.io/badge/Vue.js-35495E?style=for-the-badge\u0026logo=vuedotjs\u0026logoColor=4FC08D\n[Vue-url]: https://vuejs.org/\n[Angular.io]: https://img.shields.io/badge/Angular-DD0031?style=for-the-badge\u0026logo=angular\u0026logoColor=white\n[Angular-url]: https://angular.io/\n[Svelte.dev]: https://img.shields.io/badge/Svelte-4A4A55?style=for-the-badge\u0026logo=svelte\u0026logoColor=FF3E00\n[Svelte-url]: https://svelte.dev/\n[Laravel.com]: https://img.shields.io/badge/Laravel-FF2D20?style=for-the-badge\u0026logo=laravel\u0026logoColor=white\n[Laravel-url]: https://laravel.com\n[Bootstrap.com]: https://img.shields.io/badge/Bootstrap-563D7C?style=for-the-badge\u0026logo=bootstrap\u0026logoColor=white\n[Bootstrap-url]: https://getbootstrap.com\n[JQuery.com]: https://img.shields.io/badge/jQuery-0769AD?style=for-the-badge\u0026logo=jquery\u0026logoColor=white\n[JQuery-url]: https://jquery.com  --\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fhasura_connect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflutterando%2Fhasura_connect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fhasura_connect/lists"}