rest_client_builder 1.4.4
rest_client_builder: ^1.4.4 copied to clipboard
A Clean Architecture code-generation framework for building typed REST API clients in Dart and Flutter using annotations and build_runner.
Changelog #
All notable changes to this project will be documented in this file.
This project adheres to Semantic Versioning.
1.4.4 #
β¨ New Features #
- Native HTTP Connection Pooling Settings (
idleTimeout&maxConnectionsPerHost):- Added
idleTimeout(Duration?) andmaxConnectionsPerHost(int?) toRestApiGlobalConfiguration,RestClientConfig,BasicRestClientConfig,RestGlobalConfig, andRestClientBuilder. - Configures Dio's underlying
IOHttpClientAdapterand nativeHttpClientwith custom idle socket keep-alive duration (e.g. 90 seconds) and maximum concurrent connections per host, eliminating costly TCP/TLS handshake latency on sequential API calls. - Safely falls back to platform defaults when omitted and no-ops on non-IO platforms (e.g. Flutter Web).
- Added
1.4.3 #
π Package Split (Zero Runtime Overhead) #
- Separated Codegen from Runtime: All code-generation tools (
analyzer,build,source_gen,code_builder,dart_style,glob) have been extracted into a dedicated companion package:rest_client_builder_generator. rest_client_builderis now purely a runtime and annotation package containing Dio,RestResult, and annotations with zero transitive compiler dependencies.- This completely eliminates any potential dependency conflicts (such as Flutter SDK
metapins orobjectbox_generatoranalyzer version locks) in consumer app runtime graphs.
Consumer Setup:
dependencies:
rest_client_builder: ^1.4.3
dev_dependencies:
rest_client_builder_generator: ^1.4.3
build_runner: ^2.4.15
β¨ New Features #
-
@RestKeyMulti-Key Fallback: Introduced@RestKey(['id', '_id', 'userId'])for@RestModelfields. Deserialization tries each key in order and maps the first non-null value found. Useful for APIs returning different field names across backends (e.g., MongoDB_idvs SQLid).@RestModel() class User { const User({required this.id}); @RestKey(['id', '_id']) final String id; } -
Null-Safety for
@QueryParameters: Optional nullable query parameters (e.g.@Query('filter') String? filter) are automatically omitted from the request query map whennull.
π Documentation & Pub Score #
- Added dedicated Getting Started section to README.
- Updated all installation instructions and import paths.
1.4.2 #
β Breaking Change β Output Directory Renamed #
The default output folder for generated files has changed from
lib/rest_client_builder/ to lib/generated/.
Migration steps for existing consumers:
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
Then update any direct imports from rest_client_builder/β¦ to generated/β¦.
If you want to keep the old folder, add this to your app's build.yaml:
targets:
$default:
builders:
rest_client_builder|rest_model:
options:
output_dir: rest_client_builder
rest_client_builder|rest_api:
options:
output_dir: rest_client_builder
rest_client_builder|rest_configuration:
options:
output_dir: rest_client_builder
New Features #
-
Configurable
output_dirβ the folder where generated files land is now configurable viaoptions.output_dirin the consumer'sbuild.yaml. Default isgenerated. All cross-file import resolution inside generators automatically uses the configured folder. -
Auto-refreshed barrel export builder (
rest_export) β opt-in builder that writeslib/<output_dir>.g.dartafter every build. The barrel contains oneexportstatement per generated.dartfile inlib/<output_dir>/, sorted alphabetically. Becausebuild_runnerremoves outputs for deleted source files before this builder runs, stale exports never accumulate.Enable in your
build.yaml:targets: $default: builders: rest_client_builder|rest_export: enabled: true options: output_dir: generated # must match other buildersUsage after enabling:
import 'package:my_app/generated.g.dart'; // one import β all generated code
Bug Fixes #
-
Fixed: Flutter 3.38.x / ObjectBox compatibility β resolved an unsolvable pub constraint graph when
rest_client_builderwas used alongsideobjectbox_generator ^5.3.2on Flutter 3.38.x.Root cause:
analyzer: '>=10.2.0 <15.0.0'requiredmeta: ^1.18.0. Flutter 3.38.1 pinsmetato1.17.0, making the constraint unsatisfiable.Fix: Lowered the
analyzerlower-bound to>=8.1.1 <11.0.0β the same band used byobjectbox_generator 5.3.2. Also wideneddart_styleto'>=2.3.7 <4.0.0'and relaxedsource_gento^4.0.1.No API changes. No consumer code changes required (other than the output_dir migration above).
1.4.1 #
- Cross-File
@RestModelImport Resolution:- Fixed an issue where
@RestModelclasses referencing nested models or enums defined across separate files generated.g.dartfiles that failed to compile withMethod not found: 'rest<Type>FromJson'andThe method 'toJson' isn't defined for type '<Type>'. - The model generator now automatically inspects model field types (including types nested in
List<T>andMap<K, V>) and emits explicit imports for both the source declaration file and its generated.g.dartcounterpart. - No manual
exportstatements or consumer code changes required.
- Fixed an issue where
1.4.0 #
- Migrated from
intMilliseconds toDuration:- Replaced all raw millisecond
intfields with Dart's idiomaticDurationtype across annotations, configuration, runtime interfaces, and builders. - Annotations:
@ConnectTimeout(Duration(seconds: 10))(was@ConnectTimeout(10000)withmillisecondsproperty).@ReceiveTimeout(Duration(seconds: 30))(was@ReceiveTimeout(30000)withmillisecondsproperty).@SendTimeout(Duration(seconds: 15))(was@SendTimeout(15000)withmillisecondsproperty).@Retry(3, Duration(milliseconds: 200))(wasdelayMs: int).@Cache(duration: Duration(minutes: 5))(wasdurationMs: int).@SSE(reconnectDelay: Duration(seconds: 3))(wasreconnectMs: int).
- Configuration & Runtime Interfaces:
RestClientConfig:connectTimeout,receiveTimeout,sendTimeout,retryDelayare nowDuration.RestApiGlobalConfiguration:connectTimeout,receiveTimeout,sendTimeout,retryDelayare nowDuration?.RestRequest/BasicRestRequest:connectTimeout,receiveTimeout,sendTimeoutare nowDuration?.RestClientBuilder:.timeouts(connectTimeout: ..., receiveTimeout: ..., sendTimeout: ...)and.retry(delay: ...)now acceptDuration.RestResponseCache:put(key, response, Duration duration)now acceptsDuration.SSEEvent:retryfield is nowDuration?parsed automatically from the SSE wire format.
- Generator:
- Updated code generator to read
Durationfrom annotations and emit cleanDurationvalues into generated client code.
- Updated code generator to read
- Replaced all raw millisecond
1.3.7 #
- Restored compatibility with Flutter SDK
meta1.17.0 pin:- Relaxed the
metadependency constraint from^1.19.0to>=1.17.0 <2.0.0. - Flutter stable SDKs (e.g. Flutter 3.38.x) pin
metato1.17.0viaflutter/flutter_test. The previous tight constraint causedpub getto fail for consumers even though the package only uses@Target/TargetKindfrompackage:meta/meta_meta.dartβ both of which are fully available sincemeta 1.15.0. - No API changes. No
dependency_overridesrequired by consumers.
- Relaxed the
1.3.6 #
- Documentation & Example Improvements:
- Refined README examples with accurate import/export usage.
- Corrected streaming download result handling using
.when(). - Added documentation for missing
RestResultcombinators (.flatMap(),.mapAsync(),.flatMapAsync(),.getOrElse()). - Added full working examples for
RestClientBuilderand queue management.
- Code Quality:
- Resolved analyzer lints and removed unused generator imports.
- Added missing documentation comments on public generator builder members.
1.3.5 #
- Renamed to
@ResilientQueue(@OfflineQueuepreserved as alias):- Renamed primary annotation to
@ResilientQueueto convey network stability, breakable connection resilience, rate limiting, and server error retries. @OfflineQueueis supported as a backward-compatible typedef alias (typedef OfflineQueue = ResilientQueue;).
- Renamed primary annotation to
- Status Code Trigger Configuration (
enqueueOnStatusCodes):- Added
enqueueOnStatusCodes: List<int>(e.g.[502, 503, 504, 429]) to specify HTTP status codes that automatically trigger queueing inRestQueueInterceptor.
- Added
1.3.4 #
New Features #
-
@SSEβ Server-Sent Events Annotation (Stream<SSEEvent>):- Annotate API methods with
@SSEto subscribe to live Server-Sent Event streams (lib/src/annotations/http/sse_annotation.dart). - Spec-compliant HTML Β§9.2 parser (
SseParser) handlingdata:,event:,id:,retry:, comments (:), and multi-line data concatenation. - Direct
Stream<SSEEvent>return type support withoutFutureorRestResultwrapping. - Runtime execution support in
DioRestClient.executeSSE().
- Annotate API methods with
-
@OfflineQueueβ Resilient Offline Request Queueing:- Declarative
@OfflineQueueannotation for auto-queueing failed requests on connection drop, timeout, or 5xx server error (lib/src/annotations/queue/offline_queue_annotation.dart). RestRequestQueuein-memory queue engine with reactive live stream (itemsStream), item list (items), filtering/removal (removeWhere), and flush replay (flush).RestQueueInterceptorfor auto-enqueueing failed requests matching trigger rules.- Custom removal logic support via
RestQueueResolver.
- Declarative
1.3.3 #
New Features #
-
@HTTPβ Generic Custom HTTP Verb Annotation (lib/src/annotations/http/http_annotations.dart):
Enables non-standard HTTP verbs beyond the built-in shortcuts (@GET,@POST, etc.).
Supports WebDAV (REPORT,COPY,MOVE,LOCK), CDN (PURGE), and any custom protocol verb.
The method string is automatically uppercased.@HTTP('REPORT', '/analytics') Future<RestResult<Map<String, dynamic>>> report(@Body() Map<String, dynamic> q); -
@Streamingβ Streaming Response Annotation (lib/src/annotations/http/streaming_annotation.dart):
Marks a method to receive the HTTP response body as a rawStream<List<int>>without loading it into RAM.
Backed by Dio'sResponseType.streamunder the hood.
Return type must beFuture<RestResult<Stream<List<int>>>>.
Compile-time error if combined with@Multipartor@FormUrlEncoded.@Streaming() @GET('/files/{id}') Future<RestResult<Stream<List<int>>>> downloadFile(@Path('id') String id); -
RestResponseMapper.mapStream(): New static mapper that extracts aStream<List<int>>from a DioResponseBody(for real HTTP calls) or falls back to wrappingbodyBytes/bodyStringinto a single-chunk stream (for test clients and mocks).
Improvements #
- Visitor and writer updated to propagate
isStreamingthrough the full code generation pipeline. - Validator now rejects
@Streamingmethods that also declare@Multipartor@FormUrlEncoded. - API docs table in generated files now shows
[streaming]flag next to streamed endpoints.
1.3.2 #
- Repository Migration: Updated all repository, homepage, and package documentation references to the new Git repository
https://github.com/corevantdev/rest_client_builder. - Unit Test Stability: Updated outdated unit test assertions to match the new clean abstract class and generated
UserApiImplpattern.
1.3.1 #
- Minor Refinements: Internal documentation updates and dependency package adjustments.
1.3.0 #
- Zero-Setup DX Top-Level Getters: Automatically generates clean top-level getters (
demoApi,productApi,paymentApi) so controllers can invoke APIs directly with zeroRestClientmanagement or dependency injection boilerplate. - Pure Abstract API Declarations: Completely eliminated factory constructor requirements on
@RestApi()classes. - In-Memory Response Caching (
@Cache): Added@Cache(durationMs: ...)annotation for class and method levels. Eliminates network roundtrips for cached responses viaRestResponseCache. - Multi-Service & Microservice Architecture: Flexible support for single shared socket connection pools, microservice custom base URLs, and dedicated isolated client pools (
@RestApi(configuration: ...)). - Generator Variable Shadowing Fix: Renamed internal request variable in generated code to prevent shadowing method parameter names (
request,body, etc.).
1.2.1 #
- Refactored Code Generation: The builder now generates standalone
.g.dartfiles, completely removing the need forpartfiles. - Zero-Boilerplate Models: Removed the requirement to manually define
fromJson/toJsonmappings inside your@RestModel()classes. - Smart Imports: API generation automatically detects dependencies and imports the necessary source and generated files.
- Static Analysis & Dependencies: Updated
analyzer,dio, and other constraints. Addressed all static analysis warnings and documentation issues to achieve a perfect pub.flutter-io.cn score.
1.2.0 #
Initial stable release.
Added #
@RestApiannotation-driven REST client code generation viabuild_runner.@RestModelJSON code generation (fromJson/toJson) with fullJsonKeysupport.RestResult<T>sealed success/failure type withwhen,fold,map,flatMap,mapAsync,flatMapAsync,getOrThrow, andgetOrElse.RestErrortransport-agnostic structured error with factory constructors:unknown,validation,timeout,cancelled,connection,http, andserialization.DioRestClientwith retry, timeouts, header merging, logging, and interceptor resolution.RestPart.fromBytes/RestPart.fromBase64for web-safe multipart uploads (nodart:io).BasicCancelTokenfor cooperative cancellation withisCancelled/whenCancelled.RestProgressCallbackfor upload and download progress.@UseInterceptor/@ExcludeInterceptorper class or method.@Retry,@ConnectTimeout,@ReceiveTimeout,@SendTimeout,@EnableLogoverrides at the global, API, and endpoint levels.- Compile-time validation: duplicate routes, GET/HEAD + body, missing
@Path, invalid multipart combinations, and invalid return types. RestApiGlobalConfigurationcontract withcreateRestClient()factory (shared singleton) andcreateFreshRestClient()(isolated, for tests).RestApiClientRegistryfor shared Dio connection-pool reuse.CallbackRestClientfor easy unit testing without a network layer.DefaultInterceptorPipelinewith forward-request / reverse-response / reverse-error order.LoggingRestInterceptorwith sensitive-header redaction (Authorization,Cookie, etc.).- Generated
ApiDocs.endpointslist and dartdoc tables in every*.rest.g.dartfile. build.yamlbuilder registration β no consumerbuild.yamlrequired.- Full CRUD + multipart example under
example/. - 7 test suites covering core, runtime, validators, generator, and REST parts.