Skip to main content

Fetch data from the internet

Fetch data over the internet using the http package.

Most applications require some form of communication or data retrieval from the internet. Many apps do so through HTTP requests, which are sent from a client to a server to perform a specific action for a resource identified through a URI (Uniform Resource Identifier).

Data communicated over HTTP can technically be in any form, but using JSON (JavaScript Object Notation) is a popular choice due to its human-readability and language independent nature. The Dart SDK and ecosystem also have extensive support for JSON with multiple options to best meet your app's requirements.

In this tutorial, you will learn more about HTTP requests, URIs, and JSON. Then you will learn how to use package:http as well as Dart's JSON support in the dart:convert library to fetch, decode, then use JSON-formatted data retrieved from an HTTP server.

Background concepts

#

The following sections provide some extra background and information around the technologies and concepts used in the tutorial to facilitate fetching data from the server. To skip directly to the tutorial content, see Retrieve the necessary dependencies.

JSON

#

JSON (JavaScript Object Notation) is a data-interchange format that has become ubiquitous across application development and client-server communication. It is lightweight but also easy for humans to read and write due to being text based. With JSON, various data types and simple data structures such as lists and maps can be serialized and represented by strings.

Most languages have many implementations and parsers have become extremely fast, so you don't need to worry about interoperability or performance. For more information about the JSON format, see Introducing JSON. To learn more about working with JSON in Dart, see the Using JSON guide.

HTTP requests

#

HTTP (Hypertext Transfer Protocol) is a stateless protocol designed for transmitting documents, originally between web clients and web servers. You interacted with the protocol to load this page, as your browser uses an HTTP GET request to retrieve the contents of a page from a web server. Since its introduction, use of the HTTP protocol and its various versions have expanded to applications outside the web as well, essentially wherever communication from a client to a server is needed.

HTTP requests sent from the client to communicate with the server are composed of multiple components. HTTP libraries, such as package:http, allow you to specify the following kinds of communication:

  • An HTTP method defining the desired action, such as GET to retrieve data or POST to submit new data.
  • The location of the resource through a URI.
  • The version of HTTP being used.
  • Headers that provide extra information to the server.
  • An optional body, so the request can send data to the server, not just retrieve it.

To learn more about the HTTP protocol, check out An overview of HTTP on the mdn web docs.

URIs and URLs

#

To make an HTTP request, you need to provide a URI (Uniform Resource Identifier) to the resource. A URI is a character string that uniquely identifies a resource. A URL (Uniform Resource Locator) is a specific kind of URI that also provides the location of the resource. URLs for resources on the web contain three pieces of information. For this current page, the URL is composed of:

  • The scheme used for determining the protocol used: https
  • The authority or hostname of the server: dart.dev
  • The path to the resource: /server/fetch-data.html

There are other optional parameters as well that aren't used by the current page:

  • Parameters to customize extra behavior: ?key1=value1&key2=value2
  • An anchor, that isn't sent to the server, which points to a specific location in the resource: #uris

To learn more about URLs, see What is a URL? on the mdn web docs.

Retrieve the necessary dependencies

#

The package:http library provides a cross-platform solution for making composable HTTP requests, with optional fine-grained control.

To add a dependency on package:http, run the following dart pub add command from the top of your repo:

dart pub add http

To use package:http in your code, import it and optionally specify a library prefix:

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

To learn more specifics about package:http, see its page on the pub.dev site and its API documentation.

Build a URL

#

As previously mentioned, to make an HTTP request, you first need a URL that identifies the resource being requested or endpoint being accessed.

In Dart, URLs are represented through Uri objects. There are many ways to build an Uri, but due to its flexibility, parsing a string with Uri.parse to create one is a common solution.

The following snippet shows two ways to create a Uri object pointing to mock JSON-formatted information about package:http hosted on this site:

dart
// Parse the entire URI, including the scheme
Uri.parse('https://dart.dev/f/packages/http.json');

// Specifically create a URI with the https scheme
Uri.https('dart.dev', '/f/packages/http.json');

To learn about other ways of building and interacting with URIs, see the URI documentation.

Make a network request

#

If you just need to quickly fetch a string representation of a requested resource, you can use the top-level read function found in package:http that returns a Future<String> or throws a ClientException if the request wasn't successful. The following example uses read to retrieve the mock JSON-formatted information about package:http as a string, then prints it out:

dart
void main() async {
  final httpPackageUrl = Uri.https('dart.dev', '/f/packages/http.json');
  final httpPackageInfo = await http.read(httpPackageUrl);
  print(httpPackageInfo);
}

This results in the following JSON-formatted output, which can also be seen in your browser at /f/packages/http.json.

json
{
  "name": "http",
  "latestVersion": "1.1.2",
  "description": "A composable, multi-platform, Future-based API for HTTP requests.",
  "publisher": "dart.dev",
  "repository": "https://github.com/dart-lang/http"
}

Note the structure of the data (in this case a map), as you will need it when decoding the JSON later on.

If you need other information from the response, such as the status code or the headers, you can instead use the top-level get function that returns a Future with a Response.

The following snippet uses get to get the whole response in order to exit early if the request was not successful, which is indicated with a status code of 200:

dart
void main() async {
  final httpPackageUrl = Uri.https('dart.dev', '/f/packages/http.json');
  final httpPackageResponse = await http.get(httpPackageUrl);
  if (httpPackageResponse.statusCode != 200) {
    print('Failed to retrieve the http package!');
    return;
  }
  print(httpPackageResponse.body);
}

There are many other status codes besides 200 and your app might want to handle them differently. To learn more about what different status codes mean, see HTTP response status codes on the mdn web docs.