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,哈哈哈,修的都很快! |