chopper2 3.0.4

  • Readme
  • Changelog
  • Example
  • Installing
  • 35

Build Status codecov

Chopper is an http client generator using source_gen and inspired by Retrofit.

Usage #

Generator #

Add the generator to your dev dependencies

dependencies:
  chopper: ^[latest version]

dev_dependencies:
  build_runner: ^[latest version]
  chopper2_generator: ^[latest version]

Define and Generate your API #

// my_service.dart

import "dart:async";
import 'chopper2.dart';

part "chopper2.dart";

@ChopperApi(baseUrl: "/resources")
abstract class MyService extends ChopperService {
  static MyService create([ChopperClient client]) => _$MyService(client);

  @Get(url: "{id}")
  Future<Response> getResource(@Path() String id);

  @Get(headers: const {"foo": "bar"})
  Future<Response<Map>> getMapResource(@Query() String id);

  @Post(url: 'multi')
  @multipart
  Future<Response> postResources(
    @Part('1') Map a,
    @Part('2') Map b,
    @Part('3') String c,
  );

  @Post(url: 'file')
  @multipart
  Future<Response> postFile(
    @FileField('file') List<int> bytes,
  );
}

then run the generator

pub run build_runner build

#flutter
flutter packages pub run build_runner build

Use it #

final chopper = ChopperClient(
    baseUrl: "http://localhost:8000",
    services: [
      // the generated service
      MyService.create()
    ],
    converter: JsonConverter(),
  );

final myService = MyService.create(chopper);

final response = await myService.getMapResource("1");

chopper.close();

Or create a Chopper client and inject your generated api.

import 'chopper2.dart';

final chopper = new ChopperClient(
    baseUrl: "http://localhost:8000",
    services: [
      // the generated service
      MyService.create()
    ],
    converter: JsonConverter(),
);

final myService = chopper.service<MyService>(MyService);

Interceptors #

Request #

implement RequestInterceptor class or define function with following signature FutureOr<Request> RequestInterceptorFunc(Request request)

Request interceptor are called just before sending request

final chopper = new ChopperClient(
   interceptors: [
     (request) async => request.replace(body: {}),
   ]
);

Response #

implement ResponseInterceptor class or define function with following signature FutureOr<Response> ResponseInterceptorFunc(Response response)

Called after successfull or failed request

final chopper = new ChopperClient(
   interceptors: [
     (response) async => response.replace(body: {}),
   ]
);

Converter #

Converter is used to transform body, for example transforming a Dart object to a Map<String, dynamic>

Both converter and errorConverter are called before request and response intercptors.

errorConverter is called only on error response (statusCode < 200 || statusCode >= 300)

final chopper = new ChopperClient(
   converter: MyConverter(),
   errorConverter: MyErrorConverter()
);

More example #

Issue Tracker #

Changelog #

3.0.4 #

  • Fix a bug with multipart list

3.0.2 #

  • Maintenance release to match the version with generator

3.0.1 #

  • change the name to chopper2

3.0.0 #

Breaking change New way to handle errors if (response.isSuccessful) { final body = response.body; } else { final error = response.error; }

  • Fix error handling by introducing Response.error getter
  • Remove onError since every response are available via onResponse stream

2.5.0 #

  • Unsuccessful response are not throw anymore, use Response.isSuccessful getter or statusCode instead
  • Support HEAD request

2.4.2 #

  • Fix on JsonConverter If content type header overrided using @Post(headers: {'content-type': '...'}) The converter won't add json header and won't apply json.encode if content type is not JSON

  • add bool override on applyHeader(s) functions, true by default

  • support List<MultipartFile>

2.4.1 #

  • Deprecate @FieldField, use @PartFile instead

2.4.0 #

  • Breaking Change Response.base is now a BaseRequest instead of a Request, which means that you can't do base.body now. Please use Response.bodyBytes or Response.bodyString instead for non streaming case.
  • Now supports streams !
    • You can pass Stream<List<int>> as a body to a request
    • You can also use Stream<List<int>> as the BodyType for the response, in this case the returned response will contain a stream in body.
  • Support passing MutlipartFile (from packages:http) directly to @FileField annotation

2.3.2 #

  • Fix trailing slash when path empty

2.3.1 #

  • Default value for a path is now '' instead of '/'
  • Do not send null value for Multipart request

2.3.0 #

2.2.0 #

  • Fix converter issue on List

    • Breaking Change on Converter.convertResponse<ResultType>(response), it take a new generic type => Converter.convertResponse<ResultType, ItemType>(response)
  • deprecated Chopper.service<Type>(Type), use Chopper.getservice<Type>() instead thanks to @MichaelDark

2.1.0 #

  • fix casting issue

2.0.0 #

  • Fix type safety
  • Fix json converter
  • Handle BuiltList

2.0.0 #

  • Request is now containing baseUrl

  • Can call Request.toHttpRequest() direclty to get the http.BaseRequest will receive

  • If a full url is specified in the path (ex: @Get(path: 'https://...')), it won't be concaten with the baseUrl of the ChopperClient and the ChopperAPI

  • Add CurlInterceptor thanks @edwardaux

  • Add HttpLoggingInterceptor

  • Add FactoryConverter annotation @FactoryConverter(request: convertRequest, response: convertResponse)

  • BreakingChange

    • Method.url renamed to path
    • Converter.encode and Converter.decode removed, implement Converter.convertResponse and Converter.convertRequest` instead
    • ChopperClient.jsonApi deprecated, use a JsonConverter instead
    • ChopperClient.formUrlEncodedApi, use FormUrlEncodedConverter instead
    • remove JsonEncoded annotation, use FactoryConverter instead

1.1.0 #

  • BreakingChange Removed name parameter on ChopperApi New way to instanciate a service

      @ChopperApi()
      abstract class MyService extends ChopperService {
          static MyService create([ChopperClient client]) => _$MyService(client);
      }
    

1.0.0 #

  • Multipart request
  • form url encoded
  • add jsonAPI and formUrlEncodedApi boolean to ChopperClient
  • json and formUrlEncoding are now builtin
  • onError, onResponse, onRequest stream
  • error converter
  • add withClient constructor

0.1.1 #

  • Remove trimSlashes

0.1.0 #

  • update dart sdk

0.0.2 #

  • the generated extension is now *.chopper.dart

  • rename ServiceDefinition to ChopperApi

  • rename ChopperClient.services field to ChopperClient.apis

0.0.1 #

  • Initial version, created by Stagehand

example/main.dart

import 'package:chopper2/chopper.dart';
import 'package:chopper2/src/interceptor.dart';
import 'definition.dart';

main() async {
  final chopper = ChopperClient(
    baseUrl: "http://localhost:8000",
    services: [
      // the generated service
      MyService.create()
    ],
    converter: JsonConverter(),
  );

  final myService = chopper.getService<MyService>();

  final response = await myService.getMapResource("1");
  print(response.body);

  final list = await myService.getListResources();
  print(list.body);

  chopper.dispose();
}

Use this package as a library

1. Depend on it

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


dependencies:
  chopper2: ^3.0.4

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:chopper2/chopper2.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
38
Health:
Code health derived from static analysis. [more]
0
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
35
Learn more about scoring.

We analyzed this package on Oct 21, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.1
  • pana: 0.12.21

Platforms

Detected platforms:

Error(s) prevent platform classification:

Error(s) in lib/generated/i18n.dart: Target of URI doesn't exist: 'package:flutter/foundation.dart'.

Health issues and suggestions

Fix lib/generated/i18n.dart. (-100 points)

Analysis of lib/generated/i18n.dart failed with 36 errors, 4 hints, including:

line 3 col 8: Target of URI doesn't exist: 'package:flutter/foundation.dart'.

line 4 col 8: Target of URI doesn't exist: 'package:flutter/material.dart'.

line 11 col 20: Classes and mixins can only implement classes.

line 11 col 20: Undefined class 'WidgetsLocalizations'.

line 19 col 15: Undefined class 'BuildContext'.

Fix lib/src/annotations.dart. (-7.24 points)

Analysis of lib/src/annotations.dart reported 15 hints, including:

line 14 col 17: Use = to separate a named parameter from its default value.

line 78 col 39: Use = to separate a named parameter from its default value.

line 78 col 57: Use = to separate a named parameter from its default value.

line 84 col 25: Use = to separate a named parameter from its default value.

line 84 col 58: Use = to separate a named parameter from its default value.

Fix lib/src/base.dart. (-1.49 points)

Analysis of lib/src/base.dart reported 3 hints:

line 53 col 17: Use = to separate a named parameter from its default value.

line 55 col 26: Use = to separate a named parameter from its default value.

line 58 col 38: Use = to separate a named parameter from its default value.

Maintenance issues and suggestions

Fix platform conflicts. (-20 points)

Error(s) prevent platform classification:

Error(s) in lib/generated/i18n.dart: Target of URI doesn't exist: 'package:flutter/foundation.dart'.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
http >=0.11.0 <1.0.0 0.12.0+2
logging ^0.11.3 0.11.3+2
meta ^1.1.2 1.1.7
Transitive dependencies
async 2.4.0
charcode 1.1.2
collection 1.14.12
path 1.6.4
source_span 1.5.5
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
Dev dependencies
build_runner ^1.0.0
build_test any
chopper2_generator ^3.0.4
coverage ^0.12.2
http_parser ^3.1.3 3.1.3
pedantic ^1.0.0 1.8.0+1
test ^1.3.0
test_coverage ^0.3.0