danela 1.0.1 danela: ^1.0.1 copied to clipboard
Dart Abstract Network Layer (Danela)
Have you ever felt despair when it was time to integrate your app with yet another RESTful API?
This meant writing more boilerplate by creating new ApiManager
s and ApiRepositorie
s calling same Dio or Http methods over again.
Danela (Dart Abstract Network Layer) encapsulates the network layer logic providing a modular, customizable, efficient, and intuitive solution. Move from the boilerplate and legacy mess to the general approach.
Danela, the approach, and this image was inspired by Moya.
Installation #
# pubspec.yaml
dependencies:
danela: ^1.0.0
Usage #
Danela operates with two data types. They do nothing but define the characteristics of an action. You can compare them to the Flutter widgets that act as a blueprint for the actual UI.
Request
s describe the action of requesting something from the Internet.RequestMapper
s describe the way raw response data is processed and mapped to the outcoming model/
As for the actions over data types, there are also two concepts:
Gateway
is an interface for an object performing requests.Repository
is an interface for an object caching or storing the data gateways provide it with.
// Create a request to the Joke API
final request = const Request(
url: 'https://official-joke-api.appspot.com/random_joke',
);
// Define a mapper producing a String from a Dio's Response (since we are using Dio here)
final mapper = RequestMapper<Response, String>(
mapJson: Joke.fromJson,
onError: parseError,
);
// Create the Dio instance
final dio = Dio();
// Now we define the Gateway
final gateway = DioGateway(
dio: dio,
request: request,
mapper: mapper,
);
// Safely fetch the String result
print(await gateway.run());
// Now, let's add caching
final repository = DefaultRepository(gateway: gateway);
// We're good! Cache usage is set to true by default in the DefaultRepository
print(await repository.run(useCache: true));
Using fpdart
#
If you're a functional programming approach enjoyer, leverage its beauty and conciseness easily with Danela.
// Use a mapper with Either
final mapper = RequestMapper<Response, Either<String, Joke>>(
mapJson: (json) => Either.of(Joke.fromJson(json)),
onError: (e) => '$e',
);
// Define the gateway as usual
final gateway = DioGateway(
dio: dio,
request: request,
mapper: mapper,
);
// Wrap the run with a TaskEither
final gatewayTask = TaskEither(gateway.run);
// Or define a local extension to transform a Future to the Task
extension GatewayToTaskExt<T> on Gateway<T> {
Task<T> get toTask => Task(run);
}
Testing #
Danela is composable, so feel free to implement a MockGateway
or MockRepository
and inject it as a repository in your modules.
class MockRepository<T> implements Repository<T> {
@override
Future<T> run() => Future.delayed(
const Duration(seconds: 2),
() => Random().nextInt(5),
);
@override
void dispose() {}
}
Contacts #
The package is in developmen, so in case of problems or wishes to improve the project, feel free to create an issue on GitHub or contact me on Telegram.