{"id":13551044,"url":"https://github.com/GetDutchie/brick","last_synced_at":"2025-04-03T01:31:13.965Z","repository":{"id":39580121,"uuid":"232889008","full_name":"GetDutchie/brick","owner":"GetDutchie","description":"An intuitive way to work with persistent data in Dart","archived":false,"fork":false,"pushed_at":"2024-10-28T17:56:44.000Z","size":10031,"stargazers_count":362,"open_issues_count":7,"forks_count":28,"subscribers_count":56,"default_branch":"main","last_synced_at":"2024-10-28T19:02:30.943Z","etag":null,"topics":["dart","flutter","graphql","mobile-development","offline","rest","sqlite"],"latest_commit_sha":null,"homepage":"https://getdutchie.github.io/brick/#/","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GetDutchie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-09T19:33:01.000Z","updated_at":"2024-10-28T17:56:47.000Z","dependencies_parsed_at":"2024-05-06T02:29:34.500Z","dependency_job_id":"40b102ec-479a-42cc-be52-ac73c89b2006","html_url":"https://github.com/GetDutchie/brick","commit_stats":{"total_commits":282,"total_committers":16,"mean_commits":17.625,"dds":0.5460992907801419,"last_synced_commit":"278aa99186f53fe43670bfbe78e7fd31815a337f"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetDutchie%2Fbrick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetDutchie%2Fbrick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetDutchie%2Fbrick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetDutchie%2Fbrick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetDutchie","download_url":"https://codeload.github.com/GetDutchie/brick/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222905648,"owners_count":17055817,"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":["dart","flutter","graphql","mobile-development","offline","rest","sqlite"],"created_at":"2024-08-01T12:01:41.592Z","updated_at":"2024-11-03T21:30:57.444Z","avatar_url":"https://github.com/GetDutchie.png","language":"Dart","readme":"![An intuitive way to work with persistent data](./docs/logo.svg)\n\nAn intuitive way to work with persistent data in Dart.\n\n## [Full documentation](https://getdutchie.github.io/brick/)\n\n- [GraphQL](https://getdutchie.github.io/brick/#/offline_first/offline_first_with_graphql_repository)\n- [REST](https://getdutchie.github.io/brick/#/offline_first/offline_first_with_rest_repository)\n- [Supabase](https://getdutchie.github.io/brick/#/offline_first/offline_first_with_supabase_repository?id=repository-configuration)\n\n## Why Brick?\n\n- Out-of-the-box [offline access](packages/brick_offline_first) to data\n- [Handle and hide](packages/brick_build) complex serialization/deserialization logic\n- Single [access point](https://getdutchie.github.io/brick/#/data/repositories) and opinionated DSL\n- Automatic, [intelligently-generated migrations](https://getdutchie.github.io/brick/#/sqlite)\n- Legible [querying interface](https://getdutchie.github.io/brick/#/data/query)\n\n## What is Brick?\n\nBrick is an extensible query interface for Dart applications. It's an [all-in-one solution](https://www.youtube.com/watch?v=2noLcro9iIw) responsible for representing business data in the application, regardless of where your data comes from. Using Brick, developers can focus on implementing the application, without [concern for where the data lives](https://www.youtube.com/watch?v=jm5i7e_BQq0). Brick was inspired by the need for applications to work offline first, even if an API represents your source of truth.\n\n## Quick Start\n\n1. Add the packages:\n   ```yaml\n   dependencies:\n     # Or brick_offline_first_with_graphql\n     # Or brick_offline_first_with_supabase\n     brick_offline_first_with_rest:\n     sqflite: # optional\n   dev_dependencies:\n     # Or brick_offline_first_with_graphql_build: any\n     # Or brick_offline_first_with_supabase_build: any\n     brick_offline_first_with_rest_build:\n     build_runner:\n   ```\n1. Configure your app directory structure to match Brick's expectations:\n   ```bash\n   mkdir -p lib/brick/adapters lib/brick/db;\n   ```\n1. Add [models](docs/data/models.md) that contain your app logic. Models **must be** saved with the `.model.dart` suffix (i.e. `lib/brick/models/person.model.dart`).\n1. Run `dart run build_runner build` to generate your models and [sometimes migrations](docs/sqlite.md#intelligent-migrations). Rerun after every new model change or `dart run build_runner watch` for automatic generations. You'll need to run this again after your first migration.\n1. Extend [an existing repository](docs/data/repositories.md) or create your own (Supabase has [some exceptions](https://getdutchie.github.io/brick/#/offline_first/offline_first_with_supabase_repository)):\n\n   ```dart\n   // lib/brick/repository.dart\n   import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart';\n   import 'package:brick_rest/brick_rest.dart';\n   import 'package:brick_sqlite/brick_sqlite.dart';\n   import 'package:my_app/brick/brick.g.dart';\n   import 'package:sqflite/sqflite.dart' show databaseFactory;\n   import 'package:my_app/brick/db/schema.g.dart';\n   export 'package:brick_core/query.dart' show And, Or, Query, QueryAction, Where, WherePhrase;\n\n   class Repository extends OfflineFirstWithRestRepository {\n     Repository()\n         : super(\n             migrations: migrations,\n             restProvider: RestProvider(\n               'http://0.0.0.0:3000',\n               modelDictionary: restModelDictionary,\n             ),\n             sqliteProvider: SqliteProvider(\n               _DB_NAME,\n               databaseFactory: databaseFactory,\n               modelDictionary: sqliteModelDictionary,\n             ),\n             offlineQueueManager: RestRequestSqliteCacheManager(\n               'brick_offline_queue.sqlite',\n               databaseFactory: databaseFactory,\n             ),\n           );\n   }\n   ```\n\n1. Profit.\n\n## Usage\n\nCreate a model as the app's business logic:\n\n```dart\n// brick/models/user.dart\n@ConnectOfflineFirstWithRest()\nclass User extends OfflineFirstWithRestModel {}\n```\n\nAnd generate (de)serializing code to fetch to and from multiple providers:\n\n```bash\n$ (flutter) pub run build_runner build\n```\n\n### Fetching Data\n\nA repository fetches and returns data across multiple providers. It's the single access point for data in your app:\n\n```dart\nclass MyRepository extends OfflineFirstWithRestRepository {\n  MyRepository();\n}\n\nfinal repository = MyRepository();\n\n// Now the models can be queried:\nfinal users = await repository.get\u003cUser\u003e();\n```\n\nBehind the scenes, this repository could poll a memory cache, then SQLite, then a REST API. The repository intelligently determines how and when to use each of the providers to return the fastest, most reliable data.\n\n```dart\n// Queries can be general:\nfinal query = Query(where: [Where('lastName').contains('Muster')]);\nfinal users = await repository.get\u003cUser\u003e(query: query);\n\n// Or singular:\nfinal query = Query.where('email', 'user@example.com', limit1: true);\nfinal user = await repository.get\u003cUser\u003e(query: query);\n```\n\nQueries can also receive **reactive updates**. The subscribed stream receives all models from its query whenever the local copy is updated (e.g. when the data is hydrated in another part of the app):\n\n```dart\nfinal users = repository.subscribe\u003cUser\u003e().listen((users) {})\n```\n\n### Mutating Data\n\nOnce a model has been created, it's sent to the repository and back out to _each_ provider:\n\n```dart\nfinal user = User();\nawait repository.upsert\u003cUser\u003e(user);\n```\n\n### Associating Data\n\nRepositories can support associations and automatic (de)serialization of child models.\n\n```dart\nclass Hat extends OfflineFirstWithRestModel {\n  final String color;\n  Hat({this.color});\n}\nclass User extends OfflineFirstWithRestModel {\n  // user has many hats\n  final List\u003cHat\u003e hats;\n}\n\nfinal query = Query.where('hats', Where('color').isExactly('brown'));\nfinal usersWithBrownHats = repository.get\u003cUser\u003e(query: query);\n```\n\nBrick natively [serializes primitives, associations, and more](packages/brick_offline_first/example/lib/brick/models/kitchen_sink.model.dart).\n\nIf it's still murky, [check out Learn](https://getdutchie.github.io/brick/#/README?id=learn) for videos, tutorials, and examples that break down Brick.\n","funding_links":[],"categories":["Dart"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGetDutchie%2Fbrick","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FGetDutchie%2Fbrick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGetDutchie%2Fbrick/lists"}