Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dd49fa080
|
||
|
|
0219e3d557
|
||
|
|
3de7d01173
|
||
|
|
4183da6259
|
||
|
|
1f24a76717
|
@@ -3,6 +3,38 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## 2022-11-10
|
||||
|
||||
### Changes
|
||||
|
||||
---
|
||||
|
||||
Packages with breaking changes:
|
||||
|
||||
- There are no breaking changes in this release.
|
||||
|
||||
Packages with other changes:
|
||||
|
||||
- [`wyatt_architecture` - `v0.0.2`](#wyatt_architecture---v002)
|
||||
- [`wyatt_authentication_bloc` - `v0.2.1+6`](#wyatt_authentication_bloc---v0216)
|
||||
- [`wyatt_form_bloc` - `v0.1.0+1`](#wyatt_form_bloc---v0101)
|
||||
|
||||
Packages graduated to a stable release (see pre-releases prior to the stable version for changelog entries):
|
||||
|
||||
- `wyatt_architecture` - `v0.0.2`
|
||||
|
||||
Packages with dependency updates only:
|
||||
|
||||
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
|
||||
|
||||
- `wyatt_authentication_bloc` - `v0.2.1+6`
|
||||
- `wyatt_form_bloc` - `v0.1.0+1`
|
||||
|
||||
---
|
||||
|
||||
#### `wyatt_architecture` - `v0.0.2`
|
||||
|
||||
|
||||
## 2022-11-10
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.0.2
|
||||
|
||||
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
|
||||
|
||||
## 0.0.2-dev.0
|
||||
|
||||
- **FEAT**: add exceptions, datasources, repositories, and usecases.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
@@ -16,31 +16,159 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
|
||||
# Flutter - Wyatt Architecture
|
||||
|
||||
<p align="left">
|
||||
<a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
|
||||
|
||||
<img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
|
||||
|
||||
</a>
|
||||
<img src="https://img.shields.io/badge/SDK-Flutter-blue?style=flat-square" alt="SDK: Flutter" />
|
||||
</p>
|
||||
|
||||
Architecture for Flutter.
|
||||
|
||||
Following: <https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html>
|
||||
The Wyatt Architecture for Flutter.
|
||||
|
||||
## Features
|
||||
|
||||
- Usecase
|
||||
- Repository
|
||||
- DataSource
|
||||
- Entity
|
||||
|
||||
## Getting started
|
||||
|
||||
<!-- TODO -->
|
||||
* Usecase
|
||||
* Repository
|
||||
* DataSource
|
||||
* Entity
|
||||
|
||||
## Usage
|
||||
|
||||
<!-- TODO -->
|
||||
### Domain
|
||||
|
||||
Create your entities by extending `Entity` :
|
||||
|
||||
```dart
|
||||
class Photo extends Entity {
|
||||
final int id;
|
||||
final String url;
|
||||
|
||||
const Photo({
|
||||
required this.id,
|
||||
required this.url,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Then create the data sources by extending `BaseLocalDataSource` or `BaseRemoteDataSource` depending the type of data source.
|
||||
|
||||
```dart
|
||||
abstract class PhotoRemoteDataSource extends BaseRemoteDataSource {
|
||||
Future<Photo> getPhoto(int id);
|
||||
Future<List<Photo>> getAllPhotos({int? start, int? limit});
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Then you can create your repositories by extenting `BaseRepository` :
|
||||
|
||||
```dart
|
||||
abstract class PhotoRepository extends BaseRepository {
|
||||
FutureResult<Photo> getPhoto(int id);
|
||||
FutureResult<List<Photo>> getAllPhotos({int? start, int? limit});
|
||||
}
|
||||
```
|
||||
|
||||
> Here the repository is just a proxy of the data sources with result type (to have beautiful error handling).
|
||||
|
||||
And finaly create your different usecases by using `UseCase<Parameters, ReturnType>` :
|
||||
|
||||
```dart
|
||||
class RetrieveAllPhoto extends UseCase<QueryParameters, List<Photo>> {
|
||||
final PhotoRepository _photoRepository;
|
||||
|
||||
RetrieveAllPhotos(this._photoRepository);
|
||||
|
||||
@override
|
||||
FutureResult<List<Photo>> call(QueryParameters params) {
|
||||
final photos = _photoRepository.getAllPhotos(
|
||||
start: params.start,
|
||||
limit: params.limit,
|
||||
);
|
||||
return photos;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> In fact, here we need a new parameter object, so let's create it:
|
||||
|
||||
```dart
|
||||
class QueryParameters {
|
||||
final int? start;
|
||||
final int? limit;
|
||||
|
||||
QueryParameters(this.start, this.limit);
|
||||
}
|
||||
```
|
||||
|
||||
### Data
|
||||
|
||||
We start by creating models for photos and list of photos. You can use `freezed`. The `PhotoModel` extends `Photo` with some de/serializer capabilities. And those are used only in data layer.
|
||||
|
||||
Then implements your data sources:
|
||||
|
||||
```dart
|
||||
class PhotoApiDataSourceImpl extends PhotoRemoteDataSource {
|
||||
final MiddlewareClient _client;
|
||||
|
||||
PhotoApiDataSourceImpl(this._client);
|
||||
|
||||
@override
|
||||
Future<Photo> getPhoto(int id) async {
|
||||
final response = await _client.get(Uri.parse('/photos/$id'));
|
||||
final photo =
|
||||
PhotoModel.fromJson(jsonDecode(response.body) as Map<String, Object?>);
|
||||
return photo;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Photo>> getAllPhotos({int? start, int? limit}) async {
|
||||
final startQuery = start.isNotNull ? '_start=$start' : '';
|
||||
final limitQuery = limit.isNotNull ? '_limit=$limit' : '';
|
||||
final delimiter1 =
|
||||
(startQuery.isNotEmpty || limitQuery.isNotEmpty) ? '?' : '';
|
||||
final delimiter2 =
|
||||
(startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : '';
|
||||
final url = '/photos$delimiter1$startQuery$delimiter2$limitQuery';
|
||||
final response = await _client.get(Uri.parse(url));
|
||||
final photos =
|
||||
ListPhotoModel.fromJson({'photos': jsonDecode(response.body)});
|
||||
return photos.photos;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 1: Note that here we use `MiddlewareClient` from our http package.
|
||||
|
||||
> 2: You can create multiple implementations (one real and one mock for example).
|
||||
|
||||
And implement the repositories:
|
||||
|
||||
```dart
|
||||
class PhotoRepositoryImpl extends PhotoRepository {
|
||||
final PhotoRemoteDataSource _photoRemoteDataSource;
|
||||
|
||||
PhotoRepositoryImpl(
|
||||
this._photoRemoteDataSource,
|
||||
);
|
||||
|
||||
@override
|
||||
FutureResult<Photo> getPhoto(int id) => Result.tryCatchAsync(
|
||||
() => _photoRemoteDataSource.getPhoto(id),
|
||||
(error) => ServerException('Cannot retrieve photo $id.'),
|
||||
);
|
||||
|
||||
@override
|
||||
FutureResult<List<Photo>> getAllPhotos({int? start, int? limit}) async =>
|
||||
Result.tryCatchAsync(
|
||||
() => _photoRemoteDataSource.getAllPhotos(start: start, limit: limit),
|
||||
(error) => ServerException('Cannot retrieve all photos.'),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
That's all.
|
||||
@@ -14,4 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
abstract class BaseDataSource {}
|
||||
abstract class BaseDataSource {
|
||||
const BaseDataSource();
|
||||
}
|
||||
|
||||
+3
-1
@@ -16,4 +16,6 @@
|
||||
|
||||
import 'package:wyatt_architecture/src/domain/data_sources/base_data_source.dart';
|
||||
|
||||
abstract class BaseLocalDataSource extends BaseDataSource {}
|
||||
abstract class BaseLocalDataSource extends BaseDataSource {
|
||||
const BaseLocalDataSource();
|
||||
}
|
||||
|
||||
+3
-1
@@ -16,4 +16,6 @@
|
||||
|
||||
import 'package:wyatt_architecture/src/domain/data_sources/base_data_source.dart';
|
||||
|
||||
abstract class BaseRemoteDataSource extends BaseDataSource {}
|
||||
abstract class BaseRemoteDataSource extends BaseDataSource {
|
||||
const BaseRemoteDataSource();
|
||||
}
|
||||
|
||||
@@ -14,4 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
class BaseRepository {}
|
||||
abstract class BaseRepository {
|
||||
const BaseRepository();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
typedef FutureResult<T> = Future<Result<T, AppException>>;
|
||||
typedef StreamResult<T> = Stream<Result<T, AppException>>;
|
||||
typedef Res<T> = Result<T, AppException>;
|
||||
|
||||
// ignore: one_member_abstracts
|
||||
abstract class UseCase<Parameters, ReturnType> {
|
||||
|
||||
@@ -14,4 +14,5 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'no_param.dart';
|
||||
export 'usecase.dart';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: wyatt_architecture
|
||||
description: A new Wyatt package
|
||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_architecture
|
||||
version: 0.0.2-dev.0
|
||||
version: 0.0.2
|
||||
|
||||
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
||||
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// TODO(wyatt): Add some tests
|
||||
// Nothing to test as there is no logic in this package.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.2.1+6
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.2.1+5
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
@@ -38,7 +38,7 @@ dependencies:
|
||||
wyatt_form_bloc:
|
||||
git:
|
||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||
ref: wyatt_form_bloc-v0.1.0
|
||||
ref: wyatt_form_bloc-v0.1.0+1
|
||||
path: packages/wyatt_form_bloc
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
|
||||
@@ -39,7 +39,7 @@ dependencies:
|
||||
wyatt_form_bloc:
|
||||
git:
|
||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||
ref: wyatt_form_bloc-v0.1.0
|
||||
ref: wyatt_form_bloc-v0.1.0+1
|
||||
path: packages/wyatt_form_bloc
|
||||
|
||||
wyatt_type_utils:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: wyatt_authentication_bloc
|
||||
description: Authentication BLoC for Flutter
|
||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_authentication_bloc
|
||||
version: 0.2.1+5
|
||||
version: 0.2.1+6
|
||||
|
||||
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
||||
|
||||
@@ -25,7 +25,7 @@ dependencies:
|
||||
wyatt_form_bloc:
|
||||
git:
|
||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||
ref: wyatt_form_bloc-v0.1.0
|
||||
ref: wyatt_form_bloc-v0.1.0+1
|
||||
path: packages/wyatt_form_bloc
|
||||
|
||||
wyatt_architecture:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.1.0+1
|
||||
|
||||
- Update a dependency to the latest release.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- **REFACTOR**: refactor simple example.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: wyatt_form_bloc
|
||||
description: Manage forms in Dart & Flutter with Bloc
|
||||
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_form_bloc
|
||||
version: 0.1.0
|
||||
version: 0.1.0+1
|
||||
|
||||
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
|
||||
|
||||
@@ -16,14 +16,12 @@ dependencies:
|
||||
equatable: ^2.0.5
|
||||
|
||||
wyatt_architecture:
|
||||
git:
|
||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||
ref: wyatt_architecture-v0.0.2-dev.0
|
||||
path: packages/wyatt_architecture
|
||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||
version: ^0.0.2
|
||||
|
||||
wyatt_type_utils:
|
||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||
version: 0.0.3+1
|
||||
version: ^0.0.3+1
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
@@ -32,4 +30,4 @@ dev_dependencies:
|
||||
|
||||
wyatt_analysis:
|
||||
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
|
||||
version: 2.2.2
|
||||
version: ^2.2.2
|
||||
|
||||
Reference in New Issue
Block a user