Flutter — all you need to know about the http package

devops terminal
7 min readOct 4, 2020
photo from https://www.pexels.com/photo/abstract-art-blur-bright-373543/

Foreword…

When we are developing mobile phone apps, it is not uncommon to make API calls through the http protocol. For some cases, the target API provider would provide a library for some specific programming languages which would ease the development at once. However for most situations, the API provider only exposes the REST API layer and let developers build its own http connectivity code.

In this blog, we would take a look at the http package on Flutter, and how we could make use of the package to build our own http connectivity code.

The Sample app

We build on top of a sample app to illustrate what challenges would be encountered and, of course, how to solve them piece by piece.

The sample app consists of 3 tabs — each interacting with a REST API in a different way. Let’s start with the simplest use-case, send a query request using the http GET method.

1st tab — suggestion from the bored-activity API :)

feel bored? Get a suggestion from the API :))

The UI is pretty straight forward, we could tap on the label “Feel bored” and at once a http GET request would be sent to the API — https://www.boredapi.com/api/activity .

The response returned would be interpreted and displayed in the TextField below.

We simply use the http package’s “get” method and supply the targeted API’s url as the parameter… now all set~ Since the get method is supposed to be a Future, hence we would wait for the result before parsing the response.

Once the response returns, we can access the String content by calling the “body” property. Basically the String content is a json document; hence we could also create a class to parse the body to form an Object instance. Class _EBoredSuggestion contains a factory method “fromJson” to parse the json content backed into attributes of the class instance.

The final step is to update the UI’s TextField content and display the results within the “setState” method.

Quite simple isn’t it? If we read the documentations of the “get” method; we can also provide an optional headers Map. This Map contains all the required http header info in order to run the API. For the moment of time, we don’t need to set any specific header to call the bored-api; but on the NEXT tab, we would be setting the basic authentication headers for signin purpose.

2nd tab — making a Query to Elasticsearch Cloud Service

search against Elasticsearch Cloud Service

The UI contains 2 buttons — being tapped would send a search request to the Elasticsearch Cloud Service.

If you ever used Elasticsearch before, you know that a search is run as a http GET request, also the query syntax is supplied in the form of request body. Hm… sounds good? Everything here makes sense… except the request body! If we look back at the “get” method from the http package, we could only provide headers but not the content of the request body~Also if you look into various studies and blogs on http GET behaviours, providing contents in a GET request body is NOT suggested (?!). Various debates happened on whether we should provide additional contents to GET requests or not and if you are interested on this topic do Google a bit :)

Alright~ We are into solving the challenge, aren’t we? Now the “get” method probably won’t help on this scenario, however, the “Client” class would!!

Most programming languages provide convenient http methods such as GET, PUT, POST and DELETE; on the other hand they also provide a generic “client” which we could customise on how the http request be built and configured. Thank god in Flutter (actually Dart), we also have a “client” to serve these scenarios. Let’s take a look at the actual “client” code as below:

PS. some of the code involved a switch-case logic since the 2 buttons would perform a different search query.

We first create a “http.client” instance; then get back the Elasticsearch Cloud Services’ url, username and password from a config file — the setup and logic would be illustrated at the end of this blog. Once we got the above ready, it is time to create a http request Object:

  • with the method — “get” and
  • provides a url to access (value denoted in the config file)

Because the Elasticsearch cluster MUST be secured (by default); hence we would need to add back authentication headers. The simplest BASIC authentication is what we need, the header key is — Authorization and the value is — “Basic {{base64-encoded-user:pwd}}”. More info at HERE.

Another header is required as well, the key — Content-Type and its value — application/json. This header tells Elasticsearch that a json body would be supplied in the request.

Set the query syntax by calling the “body” method of the request; then set back the headers by calling the “addAll” method of the request.headers Map collection.

Finally use the client object to send the above customised request and wait for the response.

This time the response would be in the form of a Stream; hence would be calling the Stream’s bytesToString method to retrieve the String content. After pretty-formatting the contents, display them on the TextField … don’t forget to call the setState() as well.

Wow~ We have just created a customised http request (GET with a body content) plus configured the request with BASIC authentication info. Next would be to add a new document to the Elasticsearch Cloud Service with a POST request.

3rd tab — add a document to Elasticsearch Cloud Service

If you make it through this point; probably running a POST request is a piece of cake to you :) Indeed, we could simply use the built-in POST method— told you it is easy.

add a new document based on a Jog or Read event.

The code snippet as below:

The first thing is to get back the Elasticsearch Cloud Services’ url, username and password for authentication. Then we can directly call the “post” method and provide the above information.

The major difference between a “get” and a “post” method is the “body” could be provided~ Hence we could make the method call in 1-go. As usual we provide the BASIC authentication information through the header. Then add the query syntax (in this case the body of the new json document to be added) to the “body” parameter.

The response returned provides the “body” property to get back the String content. After pretty-formatting, we would update the UI’s TextField and display them.

That’s it~ Post without a hassle. (Maybe… :D Post without a stamp??? )

How to run the code??

Q. first… where and how to get the code

git clone -b v0.1.0 https://gitlab.com/quoeamaster/blog_flutter_http_api.git

  • now the code base would be v0.1.0

Q. hey… when I try to build the Flutter project, it states that a resource file config.json is missing?

  • yes, you would need to add back a config file under the assets folder
  • the content of the config.json would be like this:
  • es_url => the url for your cloud instance.
  • es_user => the account for authentication (probably is “elastic”)
  • es_pwd => the password for the es_user .
  • es_index => set to any index name you prefer (default is “blog_activity”)

Q. hm… I don’t have a Elasticsearch Cloud Service, but want to setup one

Q. what if… I do host a Elasticsearch cluster on my own premises PLUS I didn’t setup any authentications ~~~

  • scenario 1 -> if you host Elasticsearch on your own; simply update the config.json to the corresponding url plus the username / password pair; that should do the trick.
  • scenario 2 -> you didn’t have authentications setup for the cluster. Then you could just setup the es_url value and ignore the es_user and es_pwd. The corresponding code change would be commenting the authentication header (e.g. key: Authorization), also you would comment out the code from reading the es_user and es_pwd values (e.g. configLoader.getConfigByKey(…) ).

PS. it is suggested to secure your Elasticsearch cluster if possible. An official message / blog is available at HERE.

Closings

As usual we did a great job on exploring a journey. This time we have accomplished a few things as follows:

  • understood how the http package works
  • making requests by using the http built-in methods
  • created a custom Client to handle customisable request(s) — “get”
  • understood how to set http headers to the request
  • understood how BASIC authentication could be set for connecting a secured service (Elasticsearch Cloud Service in this example)

Lastly~ Good luck in developing :)

--

--

devops terminal

a java / golang / flutter developer, a big data scientist, a father :)