सार्वजनिक जानकारी से बना चयन मार्गदर्शन। केवल संदर्भ हेतु।
Retrofit_generator एक कोड जनरेशन टूल है जो Flutter के लिए डायो-आधारित HTTP क्लाइंट बनाता है, जो source_gen का उपयोग करता है, Retrofit और Chopper से प्रेरित है। यह चिह्नित इंटरफ़ेस से प्रकार-सुरक्षित क्लाइंट क्लासेस बनाकर API एकीकरण को सरल बनाता है, बॉइलरप्लेट कम करता है और रखरखाव में सुधार करता है। पैकेज JSON सीरियलाइज़ेशन का समर्थन करता है और Android, iOS, macOS, Windows और Linux जैसे कई प्लेटफॉर्म पर काम करता है। डेवलपर्स एनोटेशन के साथ एंडपॉइंट्स को परिभाषित करते हैं, और जनरेटर प्रभावी, साफ क्लाइंट कोड उत्पन्न करता है। संरचित, स्केलेबल REST API इंटरैक्शन की आवश्यकता वाले प्रोजेक्ट्स के लिए आदर्श है।
उपयोग
प्रकार सुरक्षित HTTP क्लाइंट उत्पन्न करना
API क्लाइंट निर्माण को स्वचालित करना
नेटवर्क परतों में बॉयलरप्लेट को कम करना
HTTP अनुरोध के लिए Dio के साथ एकीकरण
Flutter ऐप में स्केलेबल REST APIs का निर्माण
मुख्य विशेषताएँ
एनोटेशन-आधारित API परिभाषा
source_gen के माध्यम से कोड जनरेशन
Dio HTTP क्लाइंट के साथ एकीकरण
JSON सीरियलाइज़ेशन का समर्थन
क्रॉस-प्लेटफॉर्म संगतता
इनके लिए उपयुक्त
Dio का उपयोग करने वाले Flutter विकासकर्ता
रखरखाव योग्य API क्लाइंट की आवश्यकता वाली टीमें
जटिल REST API वाले प्रोजेक्ट्स
हाथ से HTTP कोड कम करना चाहते हैं विकासकर्ता
स्थिर API लेयर डिज़ाइन की आवश्यकता वाले ऐप्स
विचार योग्य बातें
कोड जनरेशन के लिए build_runner की आवश्यकता है
एनोटेशन और source_gen की समझ की आवश्यकता है
बिल्ड समय बढ़ सकता है
स्थिर API परिभाषाओं तक सीमित
सही अनुच्छेद के उपयोग पर निर्भर है
मूल README
संबंधित सोर्स रिपॉज़िटरी के मूल README का स्नैपशॉट। नवीनतम सामग्री के लिए रिपॉज़िटरी देखें।
dependencies:retrofit:^4.9.0logger:^2.6.0# for logging purposejson_annotation:^4.9.0dev_dependencies:retrofit_generator:^10.0.1build_runner:^2.6.0json_serializable:^6.10.0
You can customize the code generation behavior by creating a build.yaml file in your project root:
targets:$default:builders:retrofit_generator:options:# Control whether to add '// dart format off/on' comments (default: true)format_output:true# Enable automatic response type casting (default: true)auto_cast_response:true# Generate empty request body for methods without parameters (default: false)empty_request_body:false# Enable useResult annotation for methods (default: false)use_result:false
format_output
By default, retrofit_generator wraps the generated code with // dart format off and // dart format on comments to preserve the formatting. If you're combining retrofit with other generators (like riverpod) and need more control over formatting, you can disable this:
# dart
dart pub run build_runner build
# for watch mode (recommended during development)
dart pub run build_runner watch
Lean Builder Support (Experimental)
Retrofit now has experimental support for lean_builder, a faster build system for Dart. While lean_builder support is still under development, the infrastructure has been added for future use.
Important: lean_builder is an optional dependency and is NOT required to use retrofit_generator. It's only needed if you want to try the experimental lean_builder support.
To prepare for lean_builder support, add it to your dev_dependencies:
dev_dependencies:lean_builder:^0.1.2# Optional - only if you want to use lean_builder
Note: For now, please continue using build_runner as shown above. Full lean_builder integration will be available in a future release once lean_builder reaches stability.
Use it
import'package:dio/dio.dart';
import'package:logger/logger.dart';
import'package:retrofit_example/example.dart';
final logger = Logger();
voidmain(List<String> args) {
final dio = Dio(); // Provide a dio instance
dio.options.headers['Demo-Header'] = 'demo header'; // config your dio headers globallyfinal client = RestClient(dio);
client.getTasks().then((it) => logger.i(it));
}
More
Types
Types conversion
Before you use the type conversion, please make sure that a factory Task.fromJson(Map<String, dynamic> json) must be provided for each model class. json_serializable is recommended to be used as the serialization tool.
Retrofit supports streaming responses using @DioResponseType(ResponseType.stream). When using this annotation, the return type must be either Stream<Uint8List> (for raw bytes) or Stream<String> (for text).
import'dart:convert';
import'dart:typed_data';
import'package:dio/dio.dart'hideHeaders;
import'package:retrofit/retrofit.dart';
@RestApi(baseUrl: 'https://api.example.com')
abstractclassRestClient{
factoryRestClient(Dio dio, {String? baseUrl}) = _RestClient;
// For binary data (images, files, etc.)@GET('/download/file')
@DioResponseType(ResponseType.stream)
Stream<Uint8List> downloadFile();
// For text data (SSE, NDJSON, etc.)@GET('/events')
@DioResponseType(ResponseType.stream)
Stream<String> getServerSentEvents();
}
Note: When using Stream<String>, make sure to import dart:convert in your source file.
Server-Sent Events (SSE)
For SSE support, you can use the simple_sse package to parse the stream:
dependencies:simple_sse:^2.0.0
import'package:simple_sse/simple_sse.dart';
final client = RestClient(dio);
// Get the string stream and transform it to SSE eventsfinal eventStream = client
.getServerSentEvents()
.transform(constLineSplitter())
.transform(constSseEventTransformer());
awaitfor (final event in eventStream) {
print('Event: ${event.event}');
print('Data: ${event.data}');
print('ID: ${event.id}');
}
HTTP Header
Add a HTTP header from the parameter of the method
Add global HTTP headers to all requests in the API
You can define headers at the @RestApi level that will be automatically included in all requests:
@RestApi(
baseUrl: 'https://api.example.com',
headers: {
'User-Agent': 'MyApp/1.0.0',
'X-Platform': 'mobile',
},
)
abstractclassApiService{
factoryApiService(Dio dio, {String? baseUrl}) = _ApiService;
// This request will automatically include User-Agent and X-Platform headers@GET('/users')
Future<List<User>> getUsers();
// You can add method-specific headers that combine with global headers@GET('/profile')
@Headers(<String, dynamic>{'Authorization': 'Bearer token'})
Future<User> getProfile();
// Method-level headers override global headers with the same key@GET('/settings')
@Headers(<String, dynamic>{'X-Platform': 'web'})
Future<Settings> getSettings();
}
Note: Method-level headers (via @Headers or @Header parameter) will override global headers if they have the same key.
Error Handling
catchError(Object) can be used for capturing the exception and failed response. You can get the detailed response info from DioError.response.
client.getTask('2').then((it) {
logger.i(it);
}).catchError((obj) {
// non-200 error goes here.switch (obj.runtimeType) {
caseDioException:
// Here's the sample to get the failed response error code and messagefinal res = (obj asDioException).response;
logger.e('Got error : ${res.statusCode} -> ${res.statusMessage}');
break;
default:
break;
}
});
Errors can also be caught and handled at the client level using CallAdapters. For example:
This feature allows you to adapt the return type of a network call from one type to another.
For example:
Future → Future<Result>
This feature provides flexibility in handling API responses, enabling better integration with custom response wrappers or error handling libraries.
The CallAdapter takes the original return type R and transforms it into a new type T. This is particularly useful when working with response wrappers like Either, Result, or ApiResponse.
Below is an example using a custom CallAdapter with a Result wrapper:
If you want to use multiple endpoints to your RestClient, you should pass your base url when you initiate RestClient. Any value defined in RestApi will be ignored.
@RestApi(baseUrl: 'this url will be ignored if baseUrl is passed')
abstractclassRestClient{
factoryRestClient(Dio dio, {String? baseUrl}) = _RestClient;
}
final client = RestClient(dio, baseUrl: 'your base url');
If you want to use the base url from dio.option.baseUrl, which has lowest priority, please don't pass any parameter to RestApi annotation and RestClient's structure method.
Multithreading (Flutter only)
If you want to parse models on a separate thread, you can take advantage of the compute function, just like Dio does when converting String data responses into json objects.
For each model that you use you will need to define 2 top-level functions: