Skip to content

Instantly share code, notes, and snippets.

@ferrarafer
Last active June 19, 2021 18:16
Show Gist options
  • Save ferrarafer/fdd27cef1094d61890e80a45d48ce921 to your computer and use it in GitHub Desktop.
Save ferrarafer/fdd27cef1094d61890e80a45d48ce921 to your computer and use it in GitHub Desktop.
Where to close de http client ??
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:project/core/services/stoppable_service.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:project/core/services/local_storage_service.dart';
import 'package:project/locator.dart';
abstract class AbstractApi extends StoppableService {
static const String endpoint = 'https://www.test.com/rest.php';
static const String invalidSessionId = '{"name": "dummy"}';
static const String invalidLogin = '{"name": "dummy"}';
@protected
final storageService = locator<LocalStorageService>();
@protected
final connectionTimeout = const Duration(seconds: 5);
@protected
var client = new http.Client();
@override
void inactive() {
client.close();
super.inactive();
}
@override
void pause() {
client.close();
super.pause();
}
@override
void resume() async {
client = new http.Client();
super.resume();
}
@override
void suspending() {
client.close();
super.suspending();
}
@protected
Map<String, String> buildHttpHeaders() {
return <String, String>{
HttpHeaders.acceptEncodingHeader: 'application/json',
HttpHeaders.contentTypeHeader: 'application/x-www-form-urlencoded'
};
}
@protected
Map<String, String> buildHttpBody(String method, String restData) {
return <String, String>{
'method': method,
'input_type': 'JSON',
'response_type': 'JSON',
'rest_data': restData
};
}
@protected
Future<bool> isSessionValid() async {
http.Response response;
final String restData = json.encode({
'session': storageService.sessionId
});
try {
response = await client.post(
endpoint,
headers: buildHttpHeaders(),
body: buildHttpBody('get_user_id', restData)
).timeout(connectionTimeout);
if (response.statusCode != 200)
throw Exception('Unable to validate Session ID');
if (response.body == invalidSessionId) return false;
} on TimeoutException catch (e) {
print(e);
} catch (e) {
print(e);
}
return true;
}
@protected
bool isResponseValid(String json) {
if (json == invalidSessionId) {
return false;
}
return true;
}
@protected
bool isLoginValid(String json) {
if (json == invalidLogin) {
return false;
}
return true;
}
/// TODO: Check this behaviour
/// Is this executed?
@protected
void dispose() {
client.close();
}
}
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:project/core/models/provider.dart';
import 'package:project/core/services/api/abstract_api.dart';
class HttpApiProvider extends AbstractApi {
static List<Provider> parseProviders(String responseBody) {
var providers = List<Provider>();
var parsed = json.decode(responseBody) as Map<String, dynamic>;
var providersList = parsed['entry_list'];
for (var provider in providersList) {
providers.add(Provider.fromJson(provider['name_value_list']));
}
return providers;
}
Future<List<Provider>> fetchProviders() async {
final String query =
'''
*** Mock Query ***
''';
final String restData = json.encode({
'session': storageService.sessionId,
'query': query,
'offset': 0,
'select_fields': [
'id',
'name',
'description',
],
'max_results': null,
'deleted': 0
});
final http.Response response = await client.post(
AbstractApi.endpoint,
headers: buildHttpHeaders(),
body: buildHttpBody('get_entry_list', restData)
).catchError((error, stackTrace) {
print(e);
return [];
});
if (response.statusCode == 200) {
if (!isResponseValid(response.body)) {
return [];
}
return compute(parseProviders, response.body);
} else {
throw Exception();
}
}
}
locator.registerLazySingleton(() => HttpApiProvider());
@ferrarafer
Copy link
Author

I have some doubts:

  1. Is the method dispose from AbstractApi (HttpApiProvider instance) ever executed?
  2. Should I close the http connection when the application goes to the background and recreate it when it goes to the foreground?

Note: The instance of HttpApiProvider is a singleton as I show in locator.dart

@FilledStacks
Copy link

If you have the lifecycle manager setup then it'll definitely call the methods to close your client. The idea of closing and opening the http object doesn't make sense to me since it's not an "active streaming type object". It would make more sense with a socket connection to close and open the ports that listen to it.

For instance all my requests I create using the http library directly.

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

    if (verb == HttpRequest.Post) {
      return http.post(uri, body: body, headers: requestHeaders);
    }
    if (verb == HttpRequest.Get) {
      return http.get(uri, headers: requestHeaders);
    }
    if (verb == HttpRequest.Head) {
      return http.head(uri, headers: requestHeaders);
    }

I get it per request and don't hold onto it. Internally it uses it's own client but we don't need to dispose or manage that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment