ZetCode

Dart HttpRequest

last modified October 18, 2026

The HttpRequest class in Dart represents an incoming HTTP request received by an HttpServer. It is part of Dart's dart:io library and is available in server applications.

HttpRequest exposes the request method, URI, headers, cookies, and body. The server reads the request and writes the reply to the associated HttpResponse object.

Basic Definition

HttpRequest is a server-side API for handling HTTP requests in Dart. It is not available in browser applications, where dart:html has a different HttpRequest class.

Key features include request method and URI inspection, header access, cookie handling, and a stream-based request body. It works together with HttpServer and HttpResponse.

Basic GET Request

This example shows a server that inspects the request method and path.

main.dart
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on http://${server.address.host}:${server.port}');
  
  await for (HttpRequest request in server) {
    if (request.method == 'GET' && request.uri.path == '/') {
      request.response
        ..headers.contentType = ContentType.text
        ..write('Hello from Dart server!');
    } else {
      request.response
        ..statusCode = HttpStatus.notFound
        ..write('Not found');
    }
    await request.response.close();
  }
}

We create an HttpServer and inspect each incoming HttpRequest. The method and uri properties identify the request, and the response is sent through request.response.

$ dart main.dart
Server running on http://localhost:8080

POST Request with JSON

This example demonstrates reading a JSON request body from a POST request.

main.dart
import 'dart:io';
import 'dart:convert';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on http://${server.address.host}:${server.port}');
  
  await for (HttpRequest request in server) {
    if (request.method == 'POST' && request.uri.path == '/posts') {
      final body = await utf8.decoder.bind(request).join();
      final data = jsonDecode(body) as Map<String, dynamic>;
      
      request.response
        ..headers.contentType = ContentType.json
        ..write(jsonEncode({
          'title': data['title'],
          'body': data['body'],
          'userId': data['userId'],
          'id': 101
        }));
    } else {
      request.response
        ..statusCode = HttpStatus.notFound
        ..write('Not found');
    }
    await request.response.close();
  }
}

The request body is a stream. We decode it as UTF-8, parse the JSON data, and return a JSON response. The server responds with the created resource including an assigned ID.

$ dart main.dart
Server running on http://localhost:8080

Handling Request Headers

This example shows how to read request headers.

main.dart
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on http://${server.address.host}:${server.port}');
  
  await for (HttpRequest request in server) {
    final custom = request.headers.value('x-custom-header') ?? 'not set';
    final accept = request.headers.value(HttpHeaders.acceptHeader) ?? 'not set';
    
    request.response
      ..headers.contentType = ContentType.text
      ..write('X-Custom-Header: $custom\nAccept: $accept\n');
    await request.response.close();
  }
}

We access request headers through request.headers. Header names are case-insensitive, and value returns the first value or null when the header is absent.

$ dart main.dart
Server running on http://localhost:8080

Error Handling

This example demonstrates error handling when a request body is not valid JSON.

main.dart
import 'dart:io';
import 'dart:convert';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on http://${server.address.host}:${server.port}');
  
  await for (HttpRequest request in server) {
    if (request.method != 'POST') {
      request.response
        ..statusCode = HttpStatus.methodNotAllowed
        ..write('Only POST supported');
    } else {
      try {
        final body = await utf8.decoder.bind(request).join();
        final data = jsonDecode(body) as Map<String, dynamic>;
        request.response.write('Received: ${data['message']}');
      } on FormatException {
        request.response
          ..statusCode = HttpStatus.badRequest
          ..write('Invalid JSON');
      }
    }
    await request.response.close();
  }
}

We handle invalid JSON with a 400 Bad Request response and unsupported methods with 405 Method Not Allowed. Checking the request method and validating the body keeps the server robust.

$ dart main.dart
Server running on http://localhost:8080

File Upload

This example shows how to receive an uploaded file by streaming the request body to disk.

main.dart
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on http://${server.address.host}:${server.port}');
  
  await for (HttpRequest request in server) {
    if (request.method == 'POST' && request.uri.path == '/upload') {
      final sink = File('upload.bin').openWrite();
      await sink.addStream(request);
      await sink.close();
      
      request.response.write('Upload complete');
    } else {
      request.response
        ..statusCode = HttpStatus.notFound
        ..write('Not found');
    }
    await request.response.close();
  }
}

The request body is streamed directly to a file, so the upload is not held in memory. This approach works well for large files.

$ dart main.dart
Server running on http://localhost:8080

Best Practices

Source

Dart HttpRequest Documentation

This tutorial covered Dart's server-side HttpRequest class with practical examples showing request inspection, header access, body handling, error handling, and file uploads.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.