Skip to main content

Making HTTP Requests

1. Using http Package

Property Description Example
get() Method to send GET request http.get(Uri.parse('https://api.example.com/data'))
post() Method to send POST request http.post(Uri.parse('https://api.example.com/data'), body: {'key': 'value'})
put() Method to send PUT request http.put(Uri.parse('https://api.example.com/data/1'), body: {'key': 'updatedValue'})
delete() Method to send DELETE request http.delete(Uri.parse('https://api.example.com/data/1'))

Example: Making a GET Request

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

Future<void> fetchData() async {
  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
  );

  if (response.statusCode == 200) {
    final data = json.decode(response.body);
    print(data['title']);
  } else {
    print('Failed to load data');
  }
}

Example: Making a POST Request

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

Future<void> postData() async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/posts'),
    headers: {'Content-Type': 'application/json'},
    body: jsonEncode({
      'title': 'My New Post',
      'body': 'This is the content of my new post.',
      'userId': 1,
    }),
  );

  if (response.statusCode == 201) {
    print('Post created successfully');
  } else {
    print('Failed to create post');
  }
}
Note: The http package requires internet permission in AndroidManifest.xml and Info.plist for iOS.
Warning: Always handle potential network errors and timeouts in production apps.

2. Sending GET Requests

Property Description Example
http.get() Method to send a GET request http.get(Uri.parse('https://api.example.com/data'));
HttpClient Class for making HTTP requests final client = HttpClient();
HttpClientRequest Represents an outgoing HTTP request final request = await client.getUrl(url);
HttpClientResponse Represents an incoming HTTP response final response = await request.close();

Example: Fetching Data with http.get()

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

Future<void> fetchData() async {
  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
  );

  if (response.statusCode == 200) {
    print(response.body);
  } else {
    print('Failed to load data');
  }
}

Example: Parsing JSON Response

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

Future<Map<String, dynamic>> fetchPost() async {
  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
  );

  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else {
    throw Exception('Failed to load post');
  }
}
Note: The http package is a popular choice for making HTTP requests in Flutter. It provides a simple API for sending GET, POST, PUT, and DELETE requests.

3. Sending POST Requests

Property Description Example
url The endpoint to send the POST request to https://api.example.com/users
headers Optional headers to include in the request {'Content-Type': 'application/json', 'Authorization': 'Bearer token'}
body The data payload to send in the request body {'name': 'John', 'email': 'john@example.com'}

Example: Sending a POST Request with http Package

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

Future<http.Response> sendPostRequest() async {
  final url = 'https://api.example.com/users';
  final headers = {'Content-Type': 'application/json'};
  final body = jsonEncode({'name': 'John', 'email': 'john@example.com'});

  return await http.post(
    Uri.parse(url),
    headers: headers,
    body: body,
  );
}
Note: Ensure that the Content-Type header is set to application/json when sending JSON data.
Warning: Always handle potential errors when making HTTP requests. Use try-catch blocks to manage exceptions.

4. Sending PUT and DELETE Requests

Method Description Usage
PUT Updates a resource or creates it if it doesn't exist.
await http.put(
  Uri.parse('https://api.example.com/users/123'),
  body: {'name': 'John Doe', 'email': 'john@example.com'},
);
DELETE Deletes a resource from the server.
await http.delete(
  Uri.parse('https://api.example.com/users/123'),
);

Example: PUT Request with Headers

final response = await http.put(
  Uri.parse('https://api.example.com/users/123'),
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_token_here',
  },
  body: jsonEncode({
    'name': 'Updated Name',
    'email': 'updated@example.com',
  }),
);

Example: DELETE Request with Error Handling

try {
  final response = await http.delete(
    Uri.parse('https://api.example.com/users/123'),
  );
  if (response.statusCode == 200) {
    print('User deleted successfully');
  } else {
    print('Failed to delete user: ${response.statusCode}');
  }
} catch (e) {
  print('Error deleting user: $e');
}
Note: PUT and DELETE requests are typically used in REST APIs to update or remove resources. Ensure proper authentication headers are included when required.

5. Setting Request Headers

Header Value Type Description Example
Authorization string Used for authentication with the server Bearer <token>
Content-Type string Indicates the media type of the resource application/json
Accept string Specifies the media types that are acceptable for the response application/json
User-Agent string Identifies the client making the request Flutter App/1.0

Example: Setting Custom Headers in a GET Request

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

Future<void> fetchWithHeaders() async {
  final url = 'https://api.example.com/data';
  final headers = {
    'Authorization': 'Bearer <token>',
    'Content-Type': 'application/json',
  };

  final response = await http.get(
    Uri.parse(url),
    headers: headers,
  );

  print(response.body);
}

Example: Setting Headers in a POST Request

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

Future<void> postWithHeaders() async {
  final url = 'https://api.example.com/data';
  final headers = {
    'Authorization': 'Bearer <token>',
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  };
  final body = {
    'name': 'John Doe',
    'email': 'john@example.com',
  };

  final response = await http.post(
    Uri.parse(url),
    headers: headers,
    body: jsonEncode(body),
  );

  print(response.body);
}

6. Handling HTTP Responses

Property Description Example
statusCode Status code of the HTTP response 200, 404
headers Map of response headers {'content-type': 'application/json'}
body Response body as string or parsed JSON '{"name": "Flutter"}'

Example: Parsing JSON Response

final response = await http.get(Uri.parse('https://api.example.com/data'));
if (response.statusCode == 200) {
  final data = json.decode(response.body);
  print(data['name']);
} else {
  print('Failed to load data');
}
Note: Always check statusCode before parsing the response body to avoid runtime errors.

Response Handling Best Practices

  • Always validate statusCode before accessing response data
  • Use json.decode() to parse JSON responses
  • Handle errors gracefully with try-catch blocks

7. Parsing Response Bodies

Property Description Example
jsonDecode() Decodes a JSON string into a Dart object final Map<String, dynamic> data = jsonDecode(response.body);
response.body Raw string content of the response String body = await response.body; // Raw text
response.json() Directly parses JSON from response (if supported) final Map<String, dynamic> json = await response.json();

Example: Parsing JSON Response

import 'dart:convert';

void parseResponse(String responseBody) {
  final Map<String, dynamic> parsed = jsonDecode(responseBody);
  print(parsed['name']); // Accessing nested data
}
Note: Always handle potential FormatException when parsing JSON.

Example: Handling Nested JSON

final Map<String, dynamic> user = {
  'id': 1,
  'name': 'John Doe',
  'address': {
    'street': '123 Main St',
    'city': 'Anytown'
  }
};

final String street = user['address']['street']; // Accessing nested field

8. Implementing Request Timeouts

Property Description Default Value Notes
timeout Specifies the maximum time to wait for a response Duration(seconds: 30) Can be adjusted based on network conditions

Example: Setting a Custom Timeout

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

Future<http.Response> fetchWithTimeout() async {
  final url = Uri.parse('https://api.example.com/data');
  try {
    final response = await http.get(url, timeout: Duration(seconds: 10));
    return response;
  } catch (e) {
    if (e is TimeoutException) {
      print('Request timed out');
    }
    rethrow;
  }
}
Note: The timeout parameter in http.get and similar methods controls how long the client waits for a response before throwing a TimeoutException.
Warning: Setting a timeout too low might cause premature failures in slow networks or servers.

9. Using MultipartRequest

The MultipartRequest class in Flutter is used to send HTTP requests with multipart content, typically for file uploads. It allows you to include both form fields and binary data (like images or documents) in a single request.

Property Description Values
method The HTTP method to use (e.g., POST) 'POST'
url The endpoint URL to send the request to Uri.parse('https://example.com/upload')
fields Map of string key-value pairs to include as form fields {'name': 'John', 'email': 'john@example.com'}
files List of MultipartFile objects to upload [MultipartFile.fromPath('file', 'path/to/file.jpg')]

Example: Uploading a File with MultipartRequest

import &#x27;dart:io&#x27;;
import &#x27;package:http/io_client.dart&#x27;;

final request = MultipartRequest(
  &#x27;POST&#x27;,
  Uri.parse(&#x27;https://example.com/upload&#x27;),
);

request.fields[&#x27;name&#x27;] = &#x27;John Doe&#x27;;
request.fields[&#x27;email&#x27;] = &#x27;john@example.com&#x27;;

final file = await MultipartFile.fromPath(
  &#x27;file&#x27;,
  &#x27;/path/to/image.jpg&#x27;,
  contentType: MediaType(&#x27;image&#x27;, &#x27;jpeg&#x27;),
);

request.files.add(file);

final response = await request.send();
Note: Ensure that the file path is valid and accessible on the device when using MultipartFile.fromPath.
Warning: Large file uploads can lead to memory issues or timeouts. Consider using Stream or chunked uploads for large files.

10. Using Dio Package

Property Description Example
Base URL Root URL for all requests https://api.example.com
Headers HTTP headers to send with each request {'Authorization': 'Bearer token'}
Timeout Request timeout in milliseconds 5000

Example: Basic GET Request

import 'package:dio/dio.dart';

final dio = Dio();
Response response = await dio.get('https://api.example.com/users');
print(response.data);

Example: POST Request with Data

import 'package:dio/dio.dart';

final dio = Dio();
Map<String, dynamic> data = {
  'name': 'John Doe',
  'email': 'john@example.com'
};
Response response = await dio.post(
  'https://api.example.com/users',
  data: data
);
print(response.data);

Example: Handling Errors

import 'package:dio/dio.dart';

final dio = Dio();
try {
  Response response = await dio.get('https://api.example.com/users');
  print(response.data);
} catch (e) {
  if (e is DioException) {
    print('Error: ${e.message}');
  }
}
Note: Dio provides built-in support for interceptors, which can be used to modify requests or responses before they are handled.

Was this article helpful?