ht stands for HTTP Types. It provides a fetch-first set of Dart HTTP abstractions.
This package focuses on the type and semantics layer only. It does not implement an HTTP client or server runtime.
dart pub add htOr add it manually to pubspec.yaml:
dependencies:
ht: ^0.2.0| Category | Types |
|---|---|
| Protocol | HttpMethod, HttpStatus, HttpVersion, MimeType |
| Message | Request, RequestInit, Response, ResponseInit, Body, BodyInit |
| Header/URL | Headers, URLSearchParams |
| Binary/Form | Blob, File, FormData |
import 'package:ht/ht.dart';
Future<void> main() async {
final request = Request(
RequestInput.uri(Uri.parse('https://api.example.com/tasks')),
RequestInit(
method: HttpMethod.post,
headers: Headers({'content-type': 'application/json; charset=utf-8'}),
body: '{"title":"rewrite ht"}',
),
);
final response = Response.json(
{'ok': true},
ResponseInit(status: HttpStatus.created),
);
print(request.method); // POST
print(request.headers.get('content-type')); // application/json; charset=utf-8
print(await response.text());
}Request and Response use a single-consume body model:
- After the first
text()/bytes()/json()/blob()call (or stream read),bodyUsed == true - Reading the same instance again throws
StateError - Use
clone()when multiple reads are required
import 'package:ht/ht.dart';
Future<void> main() async {
final form = FormData()
..append('name', Multipart.text('alice'))
..append(
'avatar',
Multipart.blob(
Blob(<Object>['binary'], 'text/plain;charset=utf-8'),
'avatar.txt',
),
);
final multipart = form.encodeMultipart();
final bytes = await multipart.bytes();
print(multipart.contentType); // multipart/form-data; boundary=...
print(multipart.contentLength); // body bytes length
print(bytes.length); // same as contentLength
}Blob implements package:block Block, and BodyInit accepts Block
values directly:
import 'package:block/block.dart' as block;
import 'package:ht/ht.dart';
Future<void> main() async {
final body = block.Block(<Object>['hello'], type: 'text/plain');
final request = Request(
RequestInput.uri(Uri.parse('https://example.com')),
RequestInit(method: HttpMethod.post, body: body),
);
print(await request.text()); // hello
}Blob.slice(start, end) now follows Web Blob semantics. Negative indexes are
interpreted from the end of the blob:
final blob = Blob(<Object>['hello world'], 'text/plain;charset=utf-8');
final tail = blob.slice(-5);
print(await tail.text()); // worlddart pub get
dart format --output=none --set-exit-if-changed .
dart analyze
dart test
dart run example/main.dart