restio 0.4.3

Restio #

An HTTP Client for Dart inpired by OkHttp.

Installation #

In pubspec.yaml add the following dependency:

dependencies:
  restio: ^0.4.3

How to use #

  1. Create a instance of Restio:
final client = Restio();
  1. Create a Request:
final request = Request(
    uri: Uri.parse('https://httpbin.org/json'),
    method: HttpMethod.get,
);

or

final request = Request.get('https://httpbin.org/json');
  1. Create a Call from Request:
final call = client.newCall(request);
  1. Execute the Call and get a Response:
final response = await call.execute();

Recipes #

Performing a GET request: #

final client = Restio();
final request = Request.get('https://postman-echo.com/get');
final call = client.newCall(request);
final response = await call.execute();

Performing a POST request: #

final request = Request.post(
  'https://postman-echo.com/post',
  body: RequestBody.string(
    'This is expected to be sent back as part of response body.',
    contentType: MediaType.text,
  ),
);
final call = client.newCall(request);
final response = await call.execute();

Get response stream: #

final stream = response.body.data.stream;
await response.body.close();

Get raw response bytes: #

final bytes = await response.body.data.raw();
await response.body.close();

Get decompressed response bytes (gzip, deflate or brotli): #

final bytes = await response.body.data.decompressed();
await response.body.close();

Get response string: #

final string = await response.body.data.string();
await response.body.close();

Get response JSON: #

final json = await response.body.data.json();
await response.body.close();

Sending form data: #

final request = Request.post(
  'https://postman-echo.com/post',
  body: body: FormBody.of({
    'foo1': 'bar1',
    'foo2': 'bar2',
  }),
);
final call = client.newCall(request);
final response = await call.execute();

Sending multipart data: #

final request = Request.post(
  'https://postman-echo.com/post',
  body: MultipartBody(
    parts: [
      Part.file(
        'file1',
        'upload.txt',
        RequestBody.file(
          File('./upload.txt'),
          contentType: MediaType.text,
        ),
      ),
    ],
  ),
);
final call = client.newCall(request);
final response = await call.execute();

Posting binary data: #

// Binary data.
final postData = <int>[...];
final request = Request.post(
  'https://postman-echo.com/post',
  body: RequestBody.bytes(postData, contentType: MediaType.octetStream),
);
final call = client.newCall(request);
final response = await call.execute();

Listening for download progress: #

final ProgressCallback onProgress = (sent, total, done) {
  print('sent: $sent, total: $total, done: $done');
};

final progressClient = client.copyWith(
  onDownloadProgress: onProgress,
);

final request = Request.get('https://httpbin.org/stream-bytes/36001');

final call = client.newCall(request);
final response = await call.execute();
final data = await response.body.raw();
await response.body.close();

Listening for upload progress: #

final ProgressCallback onProgress = (sent, total, done) {
  print('sent: $sent, total: $total, done: $done');
};

final progressClient = client.copyWith(
  onUploadProgress: onProgress,
);

final request = Request.post('https://postman-echo.com/post',
  body: RequestBody.file(File('./large_file.txt'));
);

final call = client.newCall(request);
final response = await call.execute();

Pause & Resume retrieving response body data

final response = await call.execute();
final responseBody = response.body;
final data = await responseBody.raw();
await response.body.close();

// Called from any callback.
responseBody.pause();

responseBody.resume();

Interceptors #

final client = Restio(
  interceptors: [MyLogInterceptor()],
);

class MyLogInterceptor implements Interceptor {
  @override
  Future<Response> intercept(Chain chain) async {
    final request = chain.request;
    print('Sending request: $request');
    final response = await chain.proceed(chain.request);
    print('Received response: $response');
    return response;
  }
}

Authentication #

final client = Restio(
  authenticator: BasicAuthenticator(
    username: 'postman',
    password: 'password',
  ),
);

final request = Request.get('https://postman-echo.com/basic-auth');

final call = client.newCall(request);
final response = await call.execute();

Supports Bearer, Digest and Hawk authorization method too.

final client = Restio(
  cookieJar: MyCookieJar(),
);

class MyCookieJar extends CookieJar {

  @override
  Future<List<Cookie>> load(Request request) async {
    // TODO:
  }

  @override
  Future<void> save(
    Response response,
    List<Cookie> cookies,
  ) async {
    // TODO:
  }
}

Handling Errors #

try {
  final response = await call.execute();
} on CancelledException catch(e) {
  // TODO:
} on TooManyRedirectsException catch(e) {
  // TODO:
} on TimedOutException catch(e) {
  // TODO:
} on RestioException catch(e) {
  // TODO:
}

Cancellation #

final call = client.newCall(request);
final response = await call.execute();

// Cancel the request with 'cancelled' message.
call.cancel('cancelled');

Proxy #

final client = Restio(
  proxy: Proxy(
    host: 'localhost',
    port: 3001,
  ),
);

final request = Request.get('http://localhost:3000');
final call = client.newCall(request);
final response = await call.execute();

HTTP2 #

final client = Restio(isHttp2: true);
final request = Request.get('https://www.google.com/');
final call = client.newCall(request);
final response = await call.execute();

WebSocket #

final client = Restio();
final request = Request(uri: Uri.parse('wss://echo.websocket.org'));
final ws = client.newWebSocket(request);
final conn = await ws.open();

// Receive.
conn.stream.listen((dynamic data) {
  print(data);
});

// Send.
conn.addString('🎾');

await conn.close();

SSE #

final client = Restio();
final request = Request(uri: Uri.parse('https://my.sse.com'));
final sse = client.newSse(request);
final conn = await sse.open();

// Listen.
conn.stream.listen((Event event) {
  print(event.id);
  print(event.event);
  print(event.data);
});

await conn.close();

DNS #

Thanks to dart-protocol for this great dns library!

final dns = DnsOverUdp.google();
final client = Restio(
  dns: dns,
);

final request = Request.get('https://postman-echo.com/get');
final call = client.newCall(request);
final response = await call.execute();

print(response.dnsIp); // Prints the resolved IP.

Supports DnsOverHttps too.

Caching #

final cache = Cache(store: DiskCacheStore(Directory('./cache')));
final client = Restio(cache: cache);

final request = Request.get('https://postman-echo.com/get');
final call = client.newCall(request);
final response = await call.execute();

final networkResponse = response.networkResponse; // From network validation.
final cacheResponse = response.cacheResponse; // From cache.

Supports MemoryCacheStore too.

Projects using this library #

  • Restler: Restler is an Android app built with simplicity and ease of use in mind. It allows you send custom HTTP/HTTPS requests and test your REST API anywhere and anytime.

0.4.3 #

  • Fixed various bugs.

0.4.2 #

  • Fixed SSE connection bug.

0.4.1 #

  • Improvements.

0.4.0 #

  • Added support to Cache (RFC 7234).
  • Added support to SSE (Server-Sent Event).

0.3.5 #

  • Fix DNS bug.
  • Fix Brotli decompression bug.

0.3.4 #

  • Fix DNS-over-HTTPS issue.

0.3.3 #

  • Fix DNS bugs.

0.3.2 #

  • Fix DNS timeout bug.

0.3.1 #

  • Added 'dnsIp' property.

0.3.0 #

  • Added support to Brotli decode.

0.2.0+1 #

  • Lint fixes.

0.2.0 #

  • DNS;
  • Bug fixes.

0.1.0 #

  • Initial version.

example/main.dart

import 'package:restio/restio.dart';

final _client = Restio();

Future<void> main() async {
  final request = Request.get('https://api.ipify.org?format=json');
  final call = _client.newCall(request);
  final response = await call.execute();
  final dynamic data = await response.body.data.json();

  print(data['ip']);
}

Use this package as a library

1. Depend on it

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


dependencies:
  restio: ^0.4.3

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:restio/restio.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
62
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
81
Learn more about scoring.

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

  • Dart: 2.7.1
  • pana: 0.13.5

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
brotli ^0.2.2 0.2.2
crypto ^2.1.4 2.1.4
equatable ^1.0.3 1.1.0
hex ^0.1.2 0.1.2
http2 ^1.0.0 1.0.0
http_parser ^3.1.3 3.1.3
ip ^0.1.1 0.1.1
meta ^1.1.8 1.1.8
mime ^0.9.6+3 0.9.6+3
path ^1.6.4 1.6.4
raw ^0.2.0 0.2.0
string_scanner ^1.0.5 1.0.5
utf ^0.9.0+5 0.9.0+5
Transitive dependencies
charcode 1.1.3
collection 1.14.12
convert 2.1.1
fixnum 0.10.11
matcher 0.12.6
source_span 1.6.0
stack_trace 1.9.3
term_glyph 1.1.0
typed_data 1.1.6
Dev dependencies
pubspec ^0.1.2
test ^1.6.5