retrofit.dart is a type conversion dio client generator using source_gen and inspired by Chopper and Retrofit.
Add the generator to your dev dependencies
dependencies:
retrofit: any
logger: any #for logging purpose
dev_dependencies:
retrofit_generator: any
build_runner: any
import 'package:json_annotation/json_annotation.dart';
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
part 'example.g.dart';
@RestApi(baseUrl: "https://5d42a6e2bc64f90014a56ca0.mockapi.io/api/v1/")
abstract class RestClient {
factory RestClient(Dio dio, {String baseUrl}) = _RestClient;
@GET("/tasks")
Future<List<Task>> getTasks();
}
@JsonSerializable()
class Task {
String id;
String name;
String avatar;
String createdAt;
Task({this.id, this.name, this.avatar, this.createdAt});
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
Map<String, dynamic> toJson() => _$TaskToJson(this);
}
then run the generator
# dart
pub run build_runner build
# flutter
flutter pub run build_runner build
import 'package:logger/logger.dart';
import 'package:retrofit_example/example.dart';
import 'package:dio/dio.dart';
final logger = Logger();
void main(List<String> args) {
final dio = Dio(); // Provide a dio instance
dio.options.headers["Demo-Header"] = "demo header"; // config your dio headers globally
final client = RestClient(dio);
client.getTasks().then((it) => logger.i(it));
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 the recommanded to be used as the serialization tool.
...
@GET("/tasks")
Future<List<Task>> getTasks();
}
@JsonSerializable()
class Task {
String name;
Task({this.name});
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
}
The HTTP methods in the below sample are supported.
@GET("/tasks/{id}")
Future<Task> getTask(@Path("id") String id);
@PATCH("/tasks/{id}")
Future<Task> updateTaskPart(
@Path() String id, @Body() Map<String, dynamic> map);
@PUT("/tasks/{id}")
Future<Task> updateTask(@Path() String id, @Body() Task task);
@DELETE("/tasks/{id}")
Future<void> deleteTask(@Path() String id);
@POST("/tasks")
Future<Task> createTask(@Body() Task task);
@POST("http://httpbin.org/post")
Future<void> createNewTaskFromFile(@Part() File file);
@POST("http://httpbin.org/post")
@FormUrlEncoded()
Future<String> postUrlEncodedFormData(@Field() String hello);
@GET("/tasks/{id}")
Future<HttpResponse<Task>> getTask(@Path("id") String id)
@GET("/tasks")
Future<HttpResponse<List<Task>>>> getTasks()
Add a HTTP header from the parameter of the method
@GET("/tasks")
Future<Task> getTasks(@Header("Content-Type") String contentType );
Add staitc HTTP headers
@GET("/tasks")
@Headers(<String, dynamic>{
"Content-Type" : "application/json",
"Custom-Header" : "Your header"
})
Future<Task> getTasks();
catchError(Object)
should 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((Object obj) {
// non-200 error goes here.
switch (obj.runtimeType) {
case DioError:
// Here's the sample to get the failed response error code and message
final res = (obj as DioError).response;
logger.e("Got error : ${res.statusCode} -> ${res.statusMessage}");
break;
default:
}
});
}
1
phantomlimb 2020-03-18 09:24:50 +08:00
楼主我给你提了好几个 bug,哈哈哈,修的都很快!
|