Bridge between robust networking and clean data architecture. Ncc and data_shaft
ncc_data_shaft is the official glue that joins the power of Ncc (session management, auto-renewal, and network state tracking) with the architectural rigor of data_shaft (Clean Architecture, strict typing, and error handling).
This package provides a standardized RemoteDriver implementation powered by the Ncc BaseClient. It eliminates the need for manual adapters by offering pre-configured drivers and specialized data sources for both public and authenticated communication.
- 🛡️ Context-Strict Typing: The compiler prevents you from using a public client for an endpoint requiring a session (e.g., DatasourceGetSession vs DatasourceGetHttp).
- 🚀 Zero Boilerplate: Includes HttpDataShaftDriver and SessionDataShaftDriver ready to use.
- 📦 All-in-One: Seamlessly bridges data_shaft repositories with ncc session logic and interceptors.
- 🔄 Transparent Auto-Renewal: Requests failing due to expired tokens are paused; ncc handles renewal, and data_shaft retries the request seamlessly.
- ✨ Clean Architecture Ready: Built on top of data_shaft principles to ensure a decoupled and testable data layer.
Initialize the drivers by injecting the corresponding ncc client:
import 'package:ncc_data_shaft/ncc_data_shaft.dart';
// Driver for Public APIs (Uses NccClient)
final publicClient = NccClient(id: 'public-api');
final publicDriver = HttpDataShaftDriver(client: publicClient);
// Driver for Authenticated APIs (Uses SessionClient)
final authClient = MySessionClient(id: 'secure-api');
final sessionDriver = SessionDataShaftDriver(client: authClient);Create data sources by extending the specific verb and context needed:
Use DatasourceGetHttp to ensure this endpoint uses the session-less driver.
class GetProductsDataSource extends DatasourceGetHttp<ProductModel> {
GetProductsDataSource({required super.driver});
@override
GetParams? generateCallRequirement({required Params params}) {
return GetParams(baseUrl: 'https://api.example.com/products');
}
}Use DatasourcePostSession for protected endpoints. The compiler will demand a session driver, ensuring tokens are attached to the headers.
class CreateOrderDataSource extends DatasourcePostSession<OrderModel> {
CreateOrderDataSource({required super.driver});
@override
PostParams generateCallRequirement({required Params params}) {
return PostParams(
baseUrl: 'https://api.example.com/secure/orders',
encodeBody: () => jsonEncode({'itemId': params.id}),
);
}
}Wrap your DataSource in a data_shaft repository. The repository catches network exceptions and converts them into controlled domain errors.
final repository = SafeRepositoryDatasourceCallable(
dataSource: GetProductsDataSource(driver: publicDriver),
);
final result = await repository(repositoryParams: const NoParams());
result.fold(
(error) => print('Error: ${error.message}'),
(data) => print('Success: ${data.name}'),
);The package includes base classes for all standard HTTP operations, strictly tied to their security context:
| Operation | Public (HttpDataShaftDriver) | Session (SessionDataShaftDriver) |
|---|---|---|
| GET | DatasourceGetHttp | DatasourceGetSession |
| POST | DatasourcePostHttp | DatasourcePostSession |
| PUT | DatasourcePutHttp | DatasourcePutSession |
| PATCH | DatasourcePatchHttp | DatasourcePatchSession |
| DELETE | DatasourceDeleteHttp | DatasourceDeleteSession |
- Error Handling: Automatically maps exceptions to data_shaft's structured error levels: Inadmissible, OnException, and UnControl.
- Logging: Full observability of network traffic and repository logic powered by dart:developer tags like DS.REMOTE.
Customize logging by implementing HttpDatasourceObserver or RepositoryObserver:
DatasourceObserverInstances.httpDatasourceObserver = MyCustomLogStrategy();Contributions are welcome!
- Open issues for bugs or feature requests
- Fork the repo and submit a PR
- Run
dart formatanddart testbefore submitting
This project was created and is primarily maintained by:
![]() Cayetano Bañón Rubio |
![]() Eduardo Martínez Catalá | ![]() Jesus Bernabeu |
MIT © 2026 Coolosos


