Migration to Flutter Guide
Discover our battle-tested 21-step framework for a smooth and successful migration to Flutter!
Home
Glossary

HTTP requests in Flutter

What is an HTTP request in Flutter?

An HTTP request in Flutter is the standard way for an app to communicate with a backend server to fetch or send data, most often in JSON format. It is used for loading lists, submitting forms, authentication, or syncing remote content.

Flutter itself does not include networking APIs, so external packages are required.

Why does it matter in Flutter app development?

Incorrect handling of HTTP requests is one of the main reasons Flutter apps become unstable or hard to maintain. Problems such as frozen UI, duplicated logic, or missing error handling usually come from poor networking structure.

In commercial projects, networking must be predictable, testable, and separated from UI code.

How does it work?

HTTP requests in Flutter are asynchronous and return Future objects. This means the request runs in the background and does not block the UI thread.

Most examples use the http package, which provides basic methods like get, post, put, and delete.

Making HTTP requests in Flutter

For simple use cases, the http package is enough.

Example GET request

final response = await http.get(
  Uri.parse('https://api.example.com/users'), 
);

Always validate the response and handle failures before parsing data.

HTTP GET request with parameters

Query parameters should be built using Uri, not string concatenation.

final uri = Uri.https(
  'api.example.com',
  '/users',
  {'page': '1', 'limit': '20'},
);

await http.get(uri);

This avoids encoding bugs and improves readability.

Architecture: where HTTP code should live

HTTP requests should never be called directly inside widgets. Widgets are responsible for UI only.

Best practice is to place networking logic inside a dedicated layer, such as:

  • Repository (e.g. UserRepository)
  • Service or data source

This separation makes the app easier to test and maintain.

http vs dio

The http package is good for learning and small apps, but it is limited.

In larger projects, dio is often preferred because it supports:

  • Interceptors (e.g. adding auth tokens automatically)
  • Request cancellation
  • Upload/download progress
  • Global error handling

Interceptors are especially important for handling authentication and retries.

Canceling HTTP requests in Flutter

The http package does not support real request cancellation.

A common workaround is to ignore the response when a widget is disposed.

If cancellation is required (e.g. search suggestions), use dio, which provides cancel tokens.

Common mistakes to avoid

  • Performing HTTP requests inside build().
  • Ignoring network errors and timeouts.
  • Mixing UI and networking logic.
  • Assuming statusCode == 200 is the only failure case.

Best practices

  • Wrap requests in try-catch blocks.
  • Handle offline scenarios (SocketException).
  • Parse JSON into model classes immediately.
  • Keep HTTP logic outside UI.
  • Prefer HTTPS over HTTP (Android blocks cleartext traffic by default).

When to use HTTP requests?

Use HTTP requests when your app needs to:

  • communicate with REST or GraphQL APIs
  • fetch remote data
  • send user-generated content to a server

When not to use HTTP requests?

Avoid HTTP requests when:

  • data is static and can be bundled locally
  • real-time updates are required (use WebSockets)
  • offline-first behavior is critical without caching

Learn more

Flutter architecture by LeanCode

Feature-Based Flutter App Architecture - LeanCode

Read about the LeanCode approach to Flutter architecture. We highlight some of the design decisions that should be made when developing a feature in mobile apps. This includes our approach to dependency injection, state management, widget lifecycle, and data fetching.

12 Flutter & Dart Code Hacks
by LeanCode

12 Flutter & Dart Code Hacks & Best Practices – How to Write Better Code?

In this article, we’re sharing LeanCode’s 12 practical Flutter and Dart patterns that help you write less boilerplate, make your code cleaner, and catch mistakes earlier. Apply these patterns and you'll find yourself coding faster, communicating more clearly with your teammates, and spending less time debugging issues that the compiler could have caught.