---
name: "flutter-http-and-json"
description: "Make HTTP requests and encode / decode JSON in a Flutter app"
metadata:
model: "models/gemini-3.1-pro-preview"
last_modified: "Wed, 04 Mar 2026 17:55:17 GMT"
---
# flutter-http-json-networking
## Goal
Manages HTTP networking and JSON data handling in Flutter applications. Implements secure, asynchronous REST API calls (GET, POST, PUT, DELETE) using the `http` package. Handles JSON serialization, background parsing via isolates for large datasets, and structured JSON schemas for AI model integrations. Assumes the `http` package is added to `pubspec.yaml` and the environment supports Dart 3 pattern matching and null safety.
## Decision Logic
When implementing JSON parsing and serialization, evaluate the following decision tree:
1. **Payload Size:**
* If the JSON payload is small, parse synchronously on the main thread.
* If the JSON payload is large (takes >16ms to parse), use background parsing via `compute()` to avoid UI jank.
2. **Model Complexity:**
* If the data model is simple or a quick prototype, use manual serialization (`dart:convert`).
* If the data model is highly nested or part of a large production app, **STOP AND ASK THE USER:** "Should we configure `json_serializable` and `build_runner` for automated code generation?"
## Instructions
### 1. Configure Platform Permissions
Before making network requests, ensure the target platforms have the required internet permissions.
**Android (`android/app/src/main/AndroidManifest.xml`):**
```xml
```
**macOS (`macos/Runner/DebugProfile.entitlements` and `Release.entitlements`):**
```xml
com.apple.security.network.client
```
### 2. Define the JSON Data Model
Create a strongly typed Dart class to represent the JSON data. Use factory constructors for deserialization and a `toJson` method for serialization.
```dart
import 'dart:convert';
class ItemModel {
final int id;
final String title;
const ItemModel({required this.id, required this.title});
// Deserialize using Dart 3 pattern matching
factory ItemModel.fromJson(Map json) {
return switch (json) {
{'id': int id, 'title': String title} => ItemModel(id: id, title: title),
_ => throw const FormatException('Failed to parse ItemModel.'),
};
}
// Serialize to JSON
Map toJson() => {
'id': id,
'title': title,
};
}
```
### 3. Implement HTTP Operations (CRUD)
Use the `http` package to perform network requests. Always use `Uri.https` for safe URL encoding. Validate the status code and throw exceptions on failure.
```dart
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
final http.Client client;
ApiService(this.client);
// GET Request
Future fetchItem(int id) async {
final uri = Uri.https('api.example.com', '/items/$id');
final response = await client.get(uri);
if (response.statusCode == 200) {
return ItemModel.fromJson(jsonDecode(response.body) as Map);
} else {
throw Exception('Failed to load item: ${response.statusCode}');
}
}
// POST Request
Future createItem(String title) async {
final uri = Uri.https('api.example.com', '/items');
final response = await client.post(
uri,
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body: jsonEncode({'title': title}),
);
if (response.statusCode == 201) {
return ItemModel.fromJson(jsonDecode(response.body) as Map);
} else {
throw Exception('Failed to create item: ${response.statusCode}');
}
}
// DELETE Request
Future deleteItem(int id) async {
final uri = Uri.https('api.example.com', '/items/$id');
final response = await client.delete(
uri,
headers: {'Content-Type': 'application/json; charset=UTF-8'},
);
if (response.statusCode != 200) {
throw Exception('Failed to delete item: ${response.statusCode}');
}
}
}
```
### 4. Implement Background Parsing for Large JSON Arrays
If fetching a large list of objects, move the JSON decoding and mapping to a separate isolate using `compute()`.
```dart
import 'package:flutter/foundation.dart';
// Top-level function required for compute()
List parseItems(String responseBody) {
final parsed = (jsonDecode(responseBody) as List