Master the art of sending HTTP requests in Flutter using the http package. Learn to construct GET, POST, PUT, and DELETE requests, manage headers, and handle query parameters effectively.
In the world of mobile app development, interacting with web services is a common requirement. Whether you’re fetching data from a server, submitting user information, or updating resources, understanding how to send HTTP requests is crucial. In this section, we’ll explore how to construct and send various types of HTTP requests using the http
package in Flutter. We’ll cover GET, POST, PUT, and DELETE requests, discuss setting headers, sending request bodies, and managing query parameters. By the end of this section, you’ll be equipped to handle network communication in your Flutter apps effectively.
HTTP (Hypertext Transfer Protocol) is the foundation of data communication on the web. It defines methods to interact with resources, such as:
Each request type serves a specific purpose and requires different handling in terms of headers, body, and parameters.
http
PackageBefore diving into code examples, ensure you have the http
package added to your Flutter project. Add the following dependency to your pubspec.yaml
file:
dependencies:
http: ^0.13.3
Run flutter pub get
to install the package.
GET requests are used to retrieve data from a server. They can include query parameters to filter or modify the data returned.
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<void> fetchUsers(String query) async {
final response = await http.get(Uri.parse('https://api.example.com/users?search=$query'));
if (response.statusCode == 200) {
final List<dynamic> users = json.decode(response.body);
// Process the list of users
} else {
throw Exception('Failed to fetch users');
}
}
Key Points:
Uri.parse
to construct the URL with query parameters.statusCode
to determine if the request was successful.json.decode
to parse the response body.POST requests are used to send data to a server, typically to create a new resource. They often include a JSON body.
Future<void> createUser(String name, String email) async {
final response = await http.post(
Uri.parse('https://api.example.com/users'),
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: json.encode({'name': name, 'email': email}),
);
if (response.statusCode == 201) {
print('User created!');
} else {
throw Exception('Failed to create user');
}
}
Key Points:
Content-Type
to application/json
to indicate the body format.json.encode
to convert Dart objects to JSON strings.PUT requests are used to update existing resources. They require the resource’s identifier and a JSON body with updated data.
Future<void> updateUser(int id, String name, String email) async {
final response = await http.put(
Uri.parse('https://api.example.com/users/$id'),
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: json.encode({'name': name, 'email': email}),
);
if (response.statusCode == 200) {
print('User updated!');
} else {
throw Exception('Failed to update user');
}
}
Key Points:
DELETE requests are used to remove resources from a server. They typically require the resource’s identifier.
Future<void> deleteUser(int id) async {
final response = await http.delete(Uri.parse('https://api.example.com/users/$id'));
if (response.statusCode == 200) {
print('User deleted!');
} else {
throw Exception('Failed to delete user');
}
}
Key Points:
Custom headers are often required for authentication, content negotiation, or other purposes. You can set headers in any HTTP request.
Future<void> fetchProtectedData() async {
final response = await http.get(
Uri.parse('https://api.example.com/protected'),
headers: {'Authorization': 'Bearer YOUR_ACCESS_TOKEN'},
);
if (response.statusCode == 200) {
// Process protected data
} else {
throw Exception('Failed to fetch protected data');
}
}
Key Points:
Accept
headers to request specific data formats.Let’s consider a practical example where we manage user data using the above HTTP methods. We’ll create a simple Dart class to encapsulate these operations.
class UserService {
final String baseUrl = 'https://api.example.com/users';
Future<List<dynamic>> fetchUsers(String query) async {
final response = await http.get(Uri.parse('$baseUrl?search=$query'));
if (response.statusCode == 200) {
return json.decode(response.body);
} else {
throw Exception('Failed to fetch users');
}
}
Future<void> createUser(String name, String email) async {
final response = await http.post(
Uri.parse(baseUrl),
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: json.encode({'name': name, 'email': email}),
);
if (response.statusCode != 201) {
throw Exception('Failed to create user');
}
}
Future<void> updateUser(int id, String name, String email) async {
final response = await http.put(
Uri.parse('$baseUrl/$id'),
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: json.encode({'name': name, 'email': email}),
);
if (response.statusCode != 200) {
throw Exception('Failed to update user');
}
}
Future<void> deleteUser(int id) async {
final response = await http.delete(Uri.parse('$baseUrl/$id'));
if (response.statusCode != 200) {
throw Exception('Failed to delete user');
}
}
}
Below is a visual representation of how different HTTP requests interact with a server.
graph LR; A[Flutter App] --> B[GET Request] A --> C[POST Request] A --> D[PUT Request] A --> E[DELETE Request] B --> F[Retrieve Data] C --> G[Create Resource] D --> H[Update Resource] E --> I[Delete Resource]
statusCode
and handle errors gracefully.Mastering HTTP requests in Flutter is essential for building robust, data-driven applications. By understanding how to construct and send GET, POST, PUT, and DELETE requests, you can effectively interact with web services and manage data within your apps. Practice these techniques, explore the provided resources, and continue to refine your skills in networking and API integration.