Flutter HTTP Request
This section will introduce how to make HTTP network requests in Flutter applications, including GET, POST requests, and JSON data handling.
Add HTTP dependency
Add the http package in pubspec.yaml:
dependencies: http: ^1.0.0
Then run:
$ flutter pub get
Send GET request
Example: GET request
import 'dart:convert';
import 'package:http/http.dart' as http;
// Simple GET request
Future<void> fetchData() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
// Parse JSON data
final data = jsonDecode(response.body);
print('Title: ${data['title']}');
} else {
print('Request failed: ${response.statusCode}');
}
}
// GET request with parameters
Future<void> searchData(String query) async {
final uri = Uri.parse('https://api.example.com/search')
.replace(queryParameters: {'q': query, 'page': '1'});
final response = await http.get(uri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
print(Result: $data);
}
}
import 'package:http/http.dart' as http;
// Simple GET request
Future<void> fetchData() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
if (response.statusCode == 200) {
// Parse JSON data
final data = jsonDecode(response.body);
print('Title: ${data['title']}');
} else {
print('Request failed: ${response.statusCode}');
}
}
// GET request with parameters
Future<void> searchData(String query) async {
final uri = Uri.parse('https://api.example.com/search')
.replace(queryParameters: {'q': query, 'page': '1'});
final response = await http.get(uri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
print(Result: $data);
}
}
Send POST request
Example: POST request
import 'dart:convert';
import 'package:http/http.dart' as http;
// POST request - send JSON data
Future<void> postData() async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
final response = await http.post(
uri,
headers: {
'Content-Type': 'application/json', // Set request header
},
body: jsonEncode({ // Convert a Dart object to a JSON string
'title': Flutter Tutorial,
'body': 'Learning Flutter Network Requests',
'userId': 1,
}),
);
if (response.statusCode == 201) {
final data = jsonDecode(response.body);
print('Created successfully: $data');
} else {
print('Request failed: ${response.statusCode}');
}
}
// POST request - send form data
Future<void> postFormData() async {
final uri = Uri.parse('https://example.com/api/login');
final response = await http.post(
uri,
body: {
'username': 'admin',
'password': '123456',
},
);
print('Response: ${response.body}');
}
import 'package:http/http.dart' as http;
// POST request - send JSON data
Future<void> postData() async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
final response = await http.post(
uri,
headers: {
'Content-Type': 'application/json', // Set request header
},
body: jsonEncode({ // Convert a Dart object to a JSON string
'title': Flutter Tutorial,
'body': 'Learning Flutter Network Requests',
'userId': 1,
}),
);
if (response.statusCode == 201) {
final data = jsonDecode(response.body);
print('Created successfully: $data');
} else {
print('Request failed: ${response.statusCode}');
}
}
// POST request - send form data
Future<void> postFormData() async {
final uri = Uri.parse('https://example.com/api/login');
final response = await http.post(
uri,
body: {
'username': 'admin',
'password': '123456',
},
);
print('Response: ${response.body}');
}
Process JSON data
Example: JSON parsing
import 'dart:convert';
// Define data model
class Article {
final int id;
final String title;
final String body;
final User user;
Article({
required this.id,
required this.title,
required this.body,
required this.user,
});
// Parse from JSON
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
id: json['id'],
title: json['title'],
body: json['body'],
user: User.fromJson(json['user']),
);
}
// Convert to JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'body': body,
'user': user.toJson(),
};
}
}
class User {
final int id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(id: json['id'], name: json['name']);
}
Map<String, dynamic> toJson() {
return {'id': id, 'name': name};
}
}
// Usage example
void parseJson() {
final jsonString = '''
{
"id": 1,
"title": "Flutter Tutorial",
"body": "Learn Flutter",
"user": {"id": 1, "name": "Zhang San"}
}
''';
// Parse JSON string
final Map<String, dynamic> json = jsonDecode(jsonString);
final article = Article.fromJson(json);
print('Article ID: ${article.id}');
print('Author: ${article.user.name}');
}
// Define data model
class Article {
final int id;
final String title;
final String body;
final User user;
Article({
required this.id,
required this.title,
required this.body,
required this.user,
});
// Parse from JSON
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
id: json['id'],
title: json['title'],
body: json['body'],
user: User.fromJson(json['user']),
);
}
// Convert to JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'body': body,
'user': user.toJson(),
};
}
}
class User {
final int id;
final String name;
User({required this.id, required this.name});
factory User.fromJson(Map<String, dynamic> json) {
return User(id: json['id'], name: json['name']);
}
Map<String, dynamic> toJson() {
return {'id': id, 'name': name};
}
}
// Usage example
void parseJson() {
final jsonString = '''
{
"id": 1,
"title": "Flutter Tutorial",
"body": "Learn Flutter",
"user": {"id": 1, "name": "Zhang San"}
}
''';
// Parse JSON string
final Map<String, dynamic> json = jsonDecode(jsonString);
final article = Article.fromJson(json);
print('Article ID: ${article.id}');
print('Author: ${article.user.name}');
}
Error Handling
Example: Complete network request example
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
// Base URL
static const String baseUrl = 'https://jsonplaceholder.typicode.com';
// Generic GET request method
static Future<dynamic> get(String endpoint) async {
try {
final response = await http.get(
Uri.parse('$baseUrl/$endpoint'),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Network error: $e');
}
}
// Generic POST request method
static Future<dynamic> post(
String endpoint,
Map<String, dynamic> data,
) async {
try {
final response = await http.post(
Uri.parse('$baseUrl/$endpoint'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(data),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Network error: $e');
}
}
// Handle response
static dynamic _handleResponse(http.Response response) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// Successful response
if (response.body.isEmpty) {
return null;
}
return jsonDecode(response.body);
} else if (response.statusCode == 404) {
throw ApiException(Resource not found, statusCode: 404);
} else if (response.statusCode >= 500) {
throw ApiException('Server error', statusCode: response.statusCode);
} else {
throw ApiException(
'Request failed',
statusCode: response.statusCode,
);
}
}
}
// Custom exception class
class ApiException implements Exception {
final String message;
final int? statusCode;
ApiException(this.message, {this.statusCode});
@override
String toString() => 'ApiException: $message (status: $statusCode)';
}
// Usage example
Future<void> fetchArticles() async {
try {
final articles = await ApiService.get('posts');
print('Fetched ${articles.length} articles');
} on ApiException catch (e) {
print('API error: $e');
}
}
import 'package:http/http.dart' as http;
class ApiService {
// Base URL
static const String baseUrl = 'https://jsonplaceholder.typicode.com';
// Generic GET request method
static Future<dynamic> get(String endpoint) async {
try {
final response = await http.get(
Uri.parse('$baseUrl/$endpoint'),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Network error: $e');
}
}
// Generic POST request method
static Future<dynamic> post(
String endpoint,
Map<String, dynamic> data,
) async {
try {
final response = await http.post(
Uri.parse('$baseUrl/$endpoint'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(data),
);
return _handleResponse(response);
} catch (e) {
throw ApiException('Network error: $e');
}
}
// Handle response
static dynamic _handleResponse(http.Response response) {
if (response.statusCode >= 200 && response.statusCode < 300) {
// Successful response
if (response.body.isEmpty) {
return null;
}
return jsonDecode(response.body);
} else if (response.statusCode == 404) {
throw ApiException(Resource not found, statusCode: 404);
} else if (response.statusCode >= 500) {
throw ApiException('Server error', statusCode: response.statusCode);
} else {
throw ApiException(
'Request failed',
statusCode: response.statusCode,
);
}
}
}
// Custom exception class
class ApiException implements Exception {
final String message;
final int? statusCode;
ApiException(this.message, {this.statusCode});
@override
String toString() => 'ApiException: $message (status: $statusCode)';
}
// Usage example
Future<void> fetchArticles() async {
try {
final articles = await ApiService.get('posts');
print('Fetched ${articles.length} articles');
} on ApiException catch (e) {
print('API error: $e');
}
}
other extensionsIn real applications, it is recommended to encapsulate network requests into service classes to uniformly handle errors, loading states, and caching logic.