HTTP and Networking

34.1 package:http

Inject http.Client for testability (MockClient from package:http/testing.dart).

Other clients: dio (interceptors, FormData, cancellation, retries), chopper/retrofit (code-generated clients), dart:io HttpClient (low level).

import 'dart:convert';
import 'package:http/http.dart' as http;

class ApiClient {
  ApiClient({http.Client? client, this.baseUrl = 'https://jsonplaceholder.typicode.com'})
      : _client = client ?? http.Client();
  final http.Client _client;
  final String baseUrl;

  Future<List<Map<String, dynamic>>> getPosts() async {
    final response = await _client
        .get(Uri.parse('$baseUrl/posts'), headers: {'Accept': 'application/json'})
        .timeout(const Duration(seconds: 10));
    if (response.statusCode != 200) {
      throw http.ClientException('HTTP ${response.statusCode}', response.request?.url);
    }
    return (jsonDecode(response.body) as List).cast<Map<String, dynamic>>();
  }

  Future<Map<String, dynamic>> createPost(String title) async {
    final response = await _client.post(
      Uri.parse('$baseUrl/posts'),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'title': title, 'body': 'From Dart', 'userId': 1}),
    );
    return jsonDecode(response.body) as Map<String, dynamic>;
  }

  void close() => _client.close();
}

34.2 Sockets and WebSockets

import 'dart:io';
Future<void> main() async {
  final server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 4040);
  server.listen((Socket client) {
    client.listen((data) => client.add(data));   // echo
  });

  final socket = await Socket.connect('localhost', 4040);
  socket.write('hello');

  final ws = await WebSocket.connect('wss://echo.websocket.events');
  ws.add('ping');
  ws.listen(print);
}
// Cross-platform WebSockets: package:web_socket_channel
// gRPC: package:grpc. GraphQL: graphql / ferry.