Brick Your App: Five Compelling Reasons to Make Your Data Accessible

Originally published on the Flutter Community Medium

Wrangling remote data is an app is as necessary as it is challenging. Often, multiple data stores like an API and a local cache is required. Both sources need to be kept in sync, with translations layers for both and legion control statements that determine which source to use. Of course, this is just the data. At the end of the day, you still have to write your Dart or Flutter (Flart, if you will) app.

The data persistence layer of an application requires a lot of code, a lot of tears, and a lot of distraction. So we wrote Brick to be the solid foundation for your app's data.

What Exactly is Brick?

Think of a pizza shop. Every type of pizza is a model — pepperoni, cheese, sausage. The customer (your Flutter application) orders a cheese pizza. The cashier enters that order into the restaurant's ticketing system (in Brick, this is the repository). The cooks (providers) combine raw ingredients (data source, like an API or a Firebase backend) to return a complete model back to the customer.

  • A model is basic, app-specific data
  • A provider works with a remote source to send models converted into that source's expected data (JSON, SQL, Firestore Maps, etc.) and to fetch and convert that source's data into models
  • A repository fetches and sends models from provider(s) on behalf of your app

Of course, pizza shops can get complex. There are many ways to buy a pizza — premade, frozen, by the slice. Each is made by a different provider, and it's up to the repository to determine how to satisfy the order quickly or with the freshest ingredients. This is where Brick shines as the data logic layer by hydrating from a remote source and returning from a local source.

Brick handles all of this behind the scenes. When writing your Flutter app, you only write models. Don't worry about providers, repositories, or even serialization.

1. Brick makes your data accessible offline and online

When your app goes offline, don't leave your users in the dark. Brick caches requests so that when connectivity returns, all the data generated by your users is submitted.

Of course, if your app requires eager loading, make sure that process completes before rendering the rest of the application. For example, if a user has not completed the sign up process on your remote source of truth, they never access a profile page.

2. Brick focuses your data access to a single point

Instead of including complex logic throughout your app (for example, does the query match in memory? if not, does the query exist in SQLite? if not, retrieve from REST), Brick contains the logic to munge all these sources together so that one request becomes one response. It also standardizes queries between all inputs by relying on application data instead of source data:

final usersWithBrownHats = await repository.get<User>(query:
  Query.where('hats', Where.exact('color', 'brown'))

3. Brick does the heavy lifting

SQLite migrations? Automatically generated. Translation between a REST API and a memory cache? Managed. Brick even hydrates associations to provide an ActiveRecord-like experience:

4. Brick doesn't require retrofitting

Unlike other code generator libraries like json_serializable, Brick does not require adding code within existing model classes. To Brick an existing model, simply extend a Brick model and decorate:

class User extends OfflineFirstWithRestModel {

That one annotation generates all the serializing and deserializing code required to translate your model between your remote sources (seriously).

5. Brick is extensible

Got a GraphQL, websockets, or protobuf server? While these haven't been written yet (PRs are always open), Brick has extensive documentation about writing a provider and moving data to and from it.

As of writing, Brick supports two domains: OfflineFirstWithRest and OfflineFirstWithCloudFirestore.

Brick is still in an alpha-ish release, but we're stoked to release it to the community now and see where it grows. Please drop us a line for bugs or feature requests, or come by our offices in Portland and we'll grab a pizza.

More Projects