TheOtherDev/s
Posted on February 17, 2021
It is a obligatory passage for all developers, no one can skip it. Getting to know http requests and interfacing with web services is an essential part of many apps. The great thing is that, in Flutter, it's all very simple to do.
We'll look at a package in this article called, simply, http, which is published by the official Dart development team. All you need to do some networking is there and it's really easy to use (as long as you know how to use async functions in Flutter, if not, check out the official dart documentation here).
Preparation
Before starting we'll need to add http as a dependency, so let's edit our pubspec.yaml
file and add http:
dependencies:
flutter:
sdk: flutter
http: ^0.12.2 //This one
Then we'll just need to do a good old flutter pub get
and import it in our file. I will use as a test case an ideal API Wrapper in order to call a single function to do all the work for us:
import 'package:http/http.dart' as http;
//We'll use an enum to route our static function to a single HTTP method.
enum MyHttpMethod {
get,
post,
delete,
put,
}
class MyHttpWrapper{
//This is a singleton class we can use in various places of a Flutter app
MyHttpWrapper._privateConstructor();
static final MyHttpWrapper_instance = MyHttpWrapper._privateConstructor();
static MyHttpWrapperget instance {
return _instance;
}
}
We should also need to divide the URL endpoint from the eventual API in order to create the Uri
we need to call:
//Our first url is https://dummy.restapiexample.com/api/v1/employees
const String endpoint = "dummy.restapiexample.com";
const String api = "api/v1/employees";
Let's now start with the basics: GET requests!
GET requests
A GET request is absolutely easy to do, first we need to create the uri
which contains the path and query:
var uri = Uri.https(endpoint, api);
then just use the http package to obtain a Future<Response>
which represent the result of the operation with data like body and status code:
http.Response response = await http.get(uri);
print(response.statusCode); //Response status code (200)
print(response.body); //Response body ("")
The end. Great, ain't it??!
POST, DELETE and PUT
Those three methods work similarly to GET but we expect to add some body parameters. Fear not gentle developer!
With the call we can add a String body with a jsonEncoded Map<String,String>
which will be body parameters: then we only need to use http package with post
, delete
or put
method:
http.Response response = await http.post(
uri,
body: jsonEncode(<String, String>{
'param1': param1,
'param2': param2
})
);
//or http.delete or http.put
You can also jsonEncode objects as you wish, just remember to add the encoding type.
Map<String, String> parameters = Map<String, String>();
parameters['param1'] = 'param1';
parameters['param2'] = 'param2';
var encodedBody= json.encode(parameters);
http.Response response = await http.post(
uri,
body: encodedBody,
encoding: Encoding.getByName("application/json")
);
//or http.delete or http.put
Now let's start creating our API wrapper method, complete of switch-case for our enum methods:
Future<Response> callAPI(MyHttpMethod httpMethod,
String endpoint, String apiName,{ Map<String, String> apiParameters}) async {
var uri = Uri.https(endpoint, apiName, apiParameters);
var encodedBody = json.encode(parameters);
http.Response response;
switch (httpMethod) {
case MyHttpMethod.get:{
response = await http.get(uri);
}
break;
case MyHttpMethod.post:{
response = await http.post(uri, body: encodedBody, encoding: Encoding.getByName("application/json"));
}
break;
case MyHttpMethod.delete:{
response = await http.delete(uri, body: encodedBody, encoding: Encoding.getByName("application/json"));
}
break;
case MyHttpMethod.put:{
response = await http.put(uri, body: encodedBody, encoding: Encoding.getByName("application/json"));
}
break;
}
return response;
}
As final touch let's add the possibility to add custom headers to our API calls.
Add custom headers
Adding custom headers is just another Map to add to http methods:
Map<String, String> myHeaders = Map<String, String>();
myHeaders ['header1'] = 'header1';
http.Response response = await http.post(uri, headers: myHeaders);
Wrapping up
Let's now complete our API Wrapper adding headers to our callAPI function:
Future<Response> callAPI(MyHttpMethod httpMethod,
String endpoint, String apiName,{
Map<String, String> apiParameters,
Map<String, String> customHeaders}) async {
var uri = Uri.https(endpoint, apiName);
var encodedBody = json.encode(parameters);
http.Response response;
switch (httpMethod) {
case MyHttpMethod.get:{
response = await http.get(uri, headers: customHeaders);
}
break;
case MyHttpMethod.post:{
response = await http.post(uri, headers: customHeaders, body: encodedBody, encoding: Encoding.getByName("application/json"));
}
break;
case MyHttpMethod.delete:{
response = await http.delete(uri, headers: customHeaders, body: encodedBody, encoding: Encoding.getByName("application/json"));
}
break;
case MyHttpMethod.put:{
response = await http.put(uri, headers: customHeaders, body: encodedBody, encoding: Encoding.getByName("application/json"));
}
break;
}
return response;
}
Well guys, that was pretty easy, ain't it? http has many other features like, json body encoding or multi-part request but it is a bit out of scope from this article. Remember that you should not reinvent hot water, Dart team already did.
Posted on February 17, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.