fluor 0.0.1-dev

  • Readme
  • Changelog
  • Example
  • Installing
  • 30

Retrofit For Dart #

retrofit retrofit_generator Dart CI CircleCI Build Status

retrofit.dart is a type conversion dio client generator using source_gen and inspired by Chopper and Retrofit.

Usage #

Generator #

Add the generator to your dev dependencies

dependencies:
  retrofit: any
  logger: any  #for logging purpose

dev_dependencies:
  retrofit_generator: any
  build_runner: any

Define and Generate your API #

import 'package:json_annotation/json_annotation.dart';
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';

part 'example.g.dart';
part 'example.retrofit.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

Use it #

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));

More #

Type 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 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);
}

HTTP Methods #

The HTTP methods in the below sample are supported.

  @GET("/tasks/{id}")
  Future<Task> getTask(@Path("id") String id);

  @GET('/demo')
  Future<String> queries(@Queries() Map<String, dynamic> queries);

  @GET("https://httpbin.org/get")
  Future<String> namedExample(
      @Query("apikey") String apiKey,
      @Query("scope") String scope, 
      @Query("type") String type,
      @Query("from") int from
  );

  @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 orignal HTTP reponse #

  @GET("/tasks/{id}")
  Future<Response<Task>> getTask(@Path("id") String id)

  @GET("/tasks")
  Future<Response<List<Task>>>> getTasks()

HTTP Header #

  • 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();
    

Error Handling #

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:
    }
  });

}

Multiple endpoints support #

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")
abstract class RestClient {
  factory RestClient(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.

Changelog #

1.3.4 #

  • Add dart json mapper deserialize support

1.3.3 #

  • [BERAKING CHANGE] Change Part's params to named parameters from optional ones.

1.3.2 #

  • Add contentType to Part annotaion

1.3.1 #

  • Add custom options support to each request
  • fix #132

1.3.0 #

  • Bumped retrofit's SDK requirement to >=2.6.0

1.2.0 #

  • Add HttpReponse to handle original response

1.1.0 #

  • [BREAKING CHANGE] Add new Part annotation to send multipart/form-data request. Field will not be used in the future, please use Part instead.

1.0.1 #

  • Add dio response type support

1.0.0 #

  • Support dio 3.0

0.6.3 #

  • Added autoCastResponse option to RestApi and all Method annotations (default : true)
  • Added auto_cast_response to builder options.
    • Users can specify this in build.yaml as global default

      targets:
        $default:
          sources: ['lib/**']
          builders:
            retrofit_generator|retrofit:
              enabled: true
              options:
                auto_cast_response: true
      
      

0.6.2 #

  • fix: fix bad cast exception (#47)
  • add CancelToken, SendProgress, and ReceiveProgress (#46)

0.6.0 #

  • [BREAKING CHANGE] only works dart 2.2.2 and above
  • Added support to multiple clients with different base urls.

0.5.0 #

  • Fixed analysis report use retrofit.dart instead of http.dart and dio.dart to import classes

0.4.3 #

  • Updated docs and sample code

0.2.3 #

  • Added optional parameter fileName in @Field annotation for custom file name

0.2.2 #

  • add example

0.2.0 #

  • Added @Extra to pass extra options to dio requests, response, transformer and interceptors.

    Example :

    @http.POST('/path/')
    @dio.Extra({'my_key':'my_value'})
    Future<String>> myMethod();
    
  • Fixed general dart style and code conventions

  • Automatically null check with ArgumentError.checkNotNull for required parameters

  • Now SuperClasses can use forwarding/redirecting constructors instead of static instance() method

    Example :

    @RestApi(baseUrl: "https://httpbin.org/")
    abstract class RestClient {
        /// Forwarding constructor
        factory RestClient([Dio dio]) = _RestClient;
    }
    

0.1.0 #

  • fix health issues

0.0.1 #

  • init

example/lib/example.dart

import 'dart:convert';
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart' hide Headers, Response;
import 'dart:io';
import 'package:http_parser/http_parser.dart' show MediaType;
import 'serializable.dart';

part 'example.retrofit.dart';

@RestApi(baseUrl: "https://5d42a6e2bc64f90014a56ca0.mockapi.io/api/v1/")
abstract class RestClient extends Client {
  static RestClient create(Dio dio, {String baseUrl}) =>
      _RestClient(dio, baseUrl: baseUrl);

  @GET("/tags")
  Future<List<String>> getTags();
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  fluor: ^0.0.1-dev

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:fluor/dio.dart';
import 'package:fluor/http.dart';
import 'package:fluor/retrofit.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
55
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
65
Overall:
Weighted score of the above. [more]
30
Learn more about scoring.

We analyzed this package on Jul 14, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.15

Health issues and suggestions

Fix lib/src/client.dart. (-43.75 points)

Analysis of lib/src/client.dart failed with 2 errors:

line 2 col 8: Target of URI doesn't exist: 'package:retrofit/retrofit.dart'.

line 10 col 3: Undefined class 'Converter'.

Fix lib/dio.dart. (-0.50 points)

Analysis of lib/dio.dart reported 1 hint:

line 64 col 30: Avoid shadowing type parameters.

Fix lib/src/request.dart. (-0.50 points)

Analysis of lib/src/request.dart reported 1 hint:

line 1 col 8: Unused import: '../http.dart'.

Fix lib/src/response.dart. (-0.50 points)

Analysis of lib/src/response.dart reported 1 hint:

line 17 col 24: Avoid shadowing type parameters.

Maintenance issues and suggestions

No valid SDK. (-20 points)

The analysis could not detect a valid SDK that can use this package.

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Package is pre-release. (-5 points)

Pre-release versions should be used with caution; their API can change in breaking ways.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
dio ^3.0.1 3.0.9
meta ^1.1.6 1.2.2 1.3.0-nullsafety
Transitive dependencies
charcode 1.1.3
collection 1.14.13 1.15.0-nullsafety
http_parser 3.1.4
path 1.7.0
source_span 1.7.0
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.2.0 1.3.0-nullsafety