Skip to content

Detailed API Reference - Core Network

Overview

The core network library consists of classes and methods that facilitate networking in our mobile applications. This section provides a comprehensive overview of each component and its functionality.

Objects - [Enums, Abstract classes, Mixins, Classes]

Enums

Enums in core network provides a set of predefined constants/states that is used in our core network library. Enums include: HttpVerb, ApiResponseStatus.

HttpVerb

The HttpVerb enum represents the standard HTTP methods used in RESTful APIs. Each value corresponds to a specific type of HTTP request, defining the intended action to be performed on a given resource.

Enum Values:
  • POST: Used to create a new resource.
  • GET: Used to retrieve or read a resource.
  • PUT: Used to update an existing resource or create it if it doesn’t exist.
  • PATCH: Used to partially update a resource.
  • DELETE: Used to delete an existing resource.

Declaration:

dart
    enum HttpVerb { 
        POST, 
        GET, 
        PUT, 
        PATCH, 
        DELETE 
        }

ApiResponseStatus.

The ApiResponseStatus enum represents the various possible outcomes of an API request, allowing for consistent handling of different response scenarios in the network layer.

Enum Values:
  • Success: Indicates the API request was successful, and a valid response was received.
  • NoInternet: Indicates the request failed due to lack of internet connectivity.
  • Error: Represents a general error, such as a client or server error (e.g., 4xx or 5xx HTTP status codes).
  • Timeout: Indicates the request timed out due to a delay in response.
  • Unknown: Used when the status of the response cannot be determined or doesn’t fall under other categories.

Declaration:

dart
    enum ApiResponseStatus { 
        Success, 
        NoInternet, 
        Error, 
        Timeout, 
        Unknown 
        }

Abstract Classes.

Abstract classes provide methods and properties, inheriters can use or override, and implementers can use. Abstract classes in core network include:IApiRequester ApiCore.

ApiCore.

ApiCore is an abstract base class for handling core API functionality in the network layer. It establishes a standardized structure for API interactions, making it easier to implement and extend API-related features across our mobile applications. The class includes essential properties and methods for managing API requests and response processing.

Properties

IApiRequester requester:

  • An instance of IApiRequester used to handle network requests. This allows ApiCore to delegate request execution to a specific implementation of IApiRequester, making it flexible and adaptable for various networking scenarios.
Methods

bool responseHasBody({ApiResponseStatus? status}) Determines if an API response contains a body based on its status.

Parameters:

ApiResponseStatus status: An optional parameter of type ApiResponseStatus, representing the current status of the api response.

Returns:

bool: Returns true if the response status is ApiResponseStatus.Success, indicating the presence of a response body. Otherwise, returns false.

Declaration:

dart
abstract class ApiCore {
  IApiRequester requester;

  ApiCore({required this.requester});

  bool responseHasBody({ApiResponseStatus? status}) {
    if (status == ApiResponseStatus.Success) {
      return true;
    }
    return false;
  }
}

IApiRequester

ApiCore is an abstract base class for handling core API functionality in the network layer. It establishes a standardized structure for API interactions, making it easier to implement and extend API-related features across the application. The class includes essential properties and methods for managing API requests and response processing.

Properties:

  • IAppSection section: The app section associated with the request, useful for logging and analytics.
  • Serializable defaultEventData: Default data sent with analytics events for every request.
  • EventStoreApiService _analyticsApi: Used to log API requests to an external event store.
  • Map<String, http.Client> _clientPool: A static client pool to optimize HTTP client reuse, limiting the pool size to 20 clients.
  • int _poolSize: Defines the maximum number of clients stored in the client pool.

Methods:

Future<Map<String, String>> getDefaultHeaders():

Abstract method intended to retrieve default headers for each API request.

http.Client getClientFromPool({required Uri endPoint}):

Retrieves a client from the pool based on the endpoint’s authority. If the pool exceeds _poolSize, it resets by closing all active clients.

Parameters:
  • Uri EndPoint: The URI of the API endpoint.
Returns:
  • http.Client: A pooled or new HTTP client instance.

Future<RequesterResponse> makeRequest({required Future<ApiEndPoint> apiEndPoint}):

Executes a standard HTTP request with retry logic, custom headers, and error handling.

Parameters:

Future<ApiEndPoint> apiEndPoint: A future that resolves to an ApiEndPoint, containing request configuration details.

Returns:

Future<RequesterResponse>: An async response wrapper containing status, response data, and metadata.

Future<RequesterResponse> makeMultiPartRequest({...}):

Executes a multipart request to upload a file with additional data.

Parameters:
  • File file: The file to be uploaded.
  • (Map<String, String>?) body: Additional form fields.
  • String? filename: Optional file name.
  • Future<ApiEndPoint> apiEndpoint: Endpoint configuration.
Returns:
  • Future<RequesterResponse>: Response object capturing the outcome of the upload.
Parameters:
  • Future<ApiEndPoint> apiEndpoint: The endpoint to which the files will be uploaded.
Returns:
  • Future<RequesterResponse>: A structured response containing result metadata.

Future<http.Response> runRequest(ApiEndPoint request, Map<String, String> headers):

Handles synchronous HTTP requests based on HttpVerb.

Parameters:

ApiEndPoint request: Configures request type and body. (Map<String, String>) headers: Custom headers for the request.

Returns:

Future<http.Response>: HTTP response for further handling.

RequesterResponse formatErrorMessage(dynamic error, String defaultErrorMessage, http.Response? response):

Formats and handles errors, assigning specific ApiResponseStatus values for known types.

Parameters:
  • dynamic error: The error object.
  • String defaultErrorMessage: Fallback error message.
  • http.Response? response: Optional HTTP response.
Returns:

RequesterResponse: Contains error metadata and user-friendly message.

logApiRequest(...)

Logs the API request details for debugging and analytics purposes, and sends analytics data to an event store.

Parameters:
  • ApiEndPoint endPoint: API endpoint details.
  • RequesterResponse requesterResponse: Response metadata.
  • http.Response? response: Optional response for logging.

Declaration:

dart
abstract class IApiRequester {
  IAppSection section;

  Serializable? defaultEventData;

  final EventStoreApiService _analyticsApi = EventStoreApiService();

  IApiRequester({
    this.section = const ApiAppSection(),
    this.defaultEventData,
  });

  //IDefaultApiRequesterConfiguration defaultRequesterData;
  Future<Map<String, String>> getDefaultHeaders();

  //static client pool to optimize http client reuse
  static final Map<String, http.Client> _clientPool = {};

  static const int _poolSize = 20;

  http.Client getClientFromPool({required Uri endPoint}) {}

  Future<RequesterResponse> makeRequest({
    required Future<ApiEndPoint> apiEndPoint,
  }) async {}

  Future<RequesterResponse> makeMultiPartRequest({
    required File file,
    Map<String, String>? body,
    String? filename,
    required Future<ApiEndPoint> apiEndPoint,
  }) async { }


  Future<RequesterResponse> makeMultipleFilesMultiPartRequest({
    required Future<ApiEndPoint> apiEndPoint,
  }) async {}

  Future<http.Response> runRequest(
    ApiEndPoint request,
    Map<String, String> headers,
  ) {}

  RequesterResponse formatErrorMessage(
    dynamic error,
    String defaultErrorMessage,
    http.Response? response,
  ) {}

  //log
  logApiRequest({
    required ApiEndPoint endPoint,
    required RequesterResponse requesterResponse,
    required http.Response? response,
  }) async {}
}

Mixins

Mixins in core platform provide classes with built in functionalites they can use out of the box Mixins in core platform include ApiEndpointCore

ApiEndpointCore

The ApiEndPointCore mixin provides a utility method, createEndpoint, for constructing and configuring an API endpoint with standardized request details. This mixin simplifies endpoint creation by setting default headers, constructing URIs, and allowing customization through various parameters.

Methods

Future<ApiEndPoint> createEndpoint({...}):

Creates an ApiEndPoint instance, defining all necessary details for making an API request, including the HTTP method, headers, and body.

Parameters:
  • String authority: The base URL or domain (without scheme) of the API endpoint (e.g., "api.example.com").
  • String path: The relative path of the endpoint (e.g., "/path/to/resource"). Note: It should start with a forward slash (/). A warning message is logged if it doesn’t.
  • HttpVerb requestType: The HTTP method to be used (e.g., HttpVerb.GET, HttpVerb.POST). Defaults to HttpVerb.
  • Map<String, dynamic>? body: The request body for methods like POST and PUT. Defaults to an empty map if not provided.
  • Map<String, String>? headers : Additional headers to include in the request. If Content-Type is not specified, it defaults to JSON.
  • Map<String, String>? query : URL query parameters for GET requests. Defaults to body if not specified.
  • ApiActionFilter? actionFilters : Optional filters that define actions to execute before and after the API request. bool recordApiEvent : Determines if the API event should be recorded for logging or analytics. Defaults to true.
Returns:

Future<ApiEndPoint> : A future that resolves to an ApiEndPoint instance with all properties initialized.

Declaration

dart
mixin ApiEndPointCore {

  Future<ApiEndPoint> createEndpoint(
      {required String authority,
      required String path,
      requestType = HttpVerb,
      Map<String, dynamic>? body,
      Map<String, String>? headers,
      Map<String, String>? query,
      ApiActionFilter? actionFilters,
      bool recordApiEvent = true}) async {
    var defaultContentTypeHeaders = {
      'Content-Type': 'application/json; charset=UTF-8',
    };

    if(path.characters.first.toString() != "/"){
      log("❌❌ ⚠️  Warning ⚠️ ❌❌ API relative path must start with / eg /example/relative/path. This will throw assertion errors in later updates of core-platform.");
    }
    // assert(
    //   path.characters.first.toString() == "/",
    //   "path must start with a forward slash (/) character",
    // );

    //add relative headers
    if (headers != null) {
      defaultContentTypeHeaders.addAll(headers);
    }

    var requestBody = body;
    requestBody ??= {};

    final queryParams = requestType == HttpVerb.GET ? requestBody : query;
    final uri = Uri.https(authority, path, queryParams);
      print(ApiEndPoint(
        address: uri,
        baseUrl: authority,
        path: path,
        requestType: requestType,
        body: requestBody,
        headers: defaultContentTypeHeaders,
        recordApiEvent: recordApiEvent,
        actionFilters: actionFilters,
      ));
    return ApiEndPoint(
      address: uri,
      baseUrl: authority,
      path: path,
      requestType: requestType,
      body: requestBody,
      headers: defaultContentTypeHeaders,
      recordApiEvent: recordApiEvent,
      actionFilters: actionFilters,
    );
  }
}

Classes

ApiResponse<T extends Serializable>

The ApiResponse class is a generic wrapper designed to handle and structure API responses. It provides a consistent format for storing response data, response status, and HTTP status codes. By implementing the Serializable interface, ApiResponse can easily be converted to a map format for further processing or serialization.

Type Parameter

  • T extends Serializable: The type parameter T represents the response data type, constrained to types that implement the Serializable interface. This ensures that all response data can be serialized to a map format.

Constructor

ApiResponse({this.response, this.status, this.statusCode}): Initializes an ApiResponse instance with optional parameters.

Parameters:
  • T? response: The main response data of type T, which should be serializable.
  • ApiResponseStatus? status: The status of the API response (e.g., success, error, timeout).
  • int? statusCode: The HTTP status code received from the server.

Properties

  • T? response: Holds the main response data, typically a parsed response body.
  • ApiResponseStatus? status: Represents the status of the response, allowing for consistent handling of various response states.
  • int? statusCode: The HTTP status code, providing additional context for the API response.

Methods

Map<String, dynamic> toMap():
Converts the ApiResponse instance to a Map<String, dynamic> representation, which is useful for serialization or logging.

Returns:

Map<String, dynamic>: A map containing the response data in a serializable format, including the response body (if present), status, and status code.

Declaration:

dart
class ApiResponse<T extends Serializable> implements Serializable {
  T? response;
  ApiResponseStatus? status;
  int? statusCode;

  ApiResponse({this.response, this.status, this.statusCode});

  @override
  Map<String, dynamic> toMap() {
    return {
      "response": response?.toMap(),
      "status": status,
      "statusCode": statusCode,
    };
  }
}

DataResponse<T extends Serializable>

The DataResponse class is a generic wrapper designed to handle and structure data returned from API responses. It standardizes response fields like data, message, and status, while also providing flexibility for different JSON structures via the fromJson and fromJString factory constructors. DataResponse implements Serializable, allowing easy conversion to a map format.

Type Parameter

  • T extends Serializable: The generic type parameter T represents the type of data being returned, constrained to types that implement the Serializable interface. This ensures that data can be serialized as part of the DataResponse.

Constructor

DataResponse({...}): Initializes a DataResponse instance with the following fields:

Parameters:
  • T? data: The main response data of type T, which should be serializable.
  • String? developerMessage : A message intended for developers, providing additional details about the response.
  • bool error : Indicates whether an error occurred. Defaults to false.
  • String? message: A general message about the response, often user-facing.
  • String status: The status of the response, required to indicate the response state.
  • String? responseCode: The response code returned from the API, for additional context or error handling.

Factory Constructors

DataResponse.fromJson(Map<String, dynamic>? json, Function(Map<String, dynamic>?) create)

Parses a JSON object and creates a DataResponse instance. It uses helper functions to handle potential variations in field names and missing values in the JSON.

Parameters:
  • Map<String, dynamic>? json: The JSON map from which to parse data.
  • Function(Map<String, dynamic>?) create: A function that parses the data field into type T.
DataResponse.fromJString(Map<String, dynamic>? json, Function(String?) create)

An alternative constructor that creates a DataResponse instance from JSON, but allows for parsing data as a simple String. It’s particularly useful for responses where data may not be a nested structure.

Parameters:
  • (Map<String, dynamic>?) json: The JSON map from which to parse data.
  • Function(String?) create: A function that parses the data field as a String.

Properties

  • T? data: Holds the primary response data of type T.
  • String? developerMessage: A message aimed at developers for debugging or technical context.
  • bool error: Indicates if the response contains an error. Defaults to false.
  • String? message: A general, often user-friendly message describing the response.
  • String status : The status of the response (e.g., “success”, “failure”), required to indicate the overall response outcome.
  • String? responseCode: The response code from the server, which may provide more specific information on the response type or any errors.

Methods

Map<String, dynamic> toMap()

Converts the DataResponse instance to a Map<String, dynamic>, useful for serialization or logging.

Returns:
  • Map<String, dynamic>: A map representation of the DataResponse object, including keys for data, developerMessage, error, message, and status.
Declaration:
dart
    class DataResponse<T extends Serializable> implements Serializable {
  T? data;
  String? developerMessage;
  bool error;
  String? message;
  String status;
  String? responseCode;

  DataResponse({
    this.data,
    this.developerMessage,
    this.error = false,
    this.message,
    this.responseCode,
    required this.status,
  });

  factory DataResponse.fromJson(
    Map<String, dynamic>? json,
    Function(Map<String, dynamic>?) create,
  ) {
 
  }

  factory DataResponse.fromJString(
      Map<String, dynamic>? json, Function(String?) create) {}

  @override
  Map<String, dynamic> toMap() {}
}

ListDataResponse<T extends Serializable>

The ListDataResponse class is a generic wrapper for handling paginated API responses that contain a list of items. It structures the response fields in a standardized format, including metadata related to pagination, error status, and developer messages. By implementing the Serializable interface, it provides easy conversion to a map format for further processing or logging.

Type Parameter

  • T extends Serializable: The type parameter T represents each item in the response data list, constrained to types that implement Serializable. This ensures that all list items can be serialized to a map format.

Constructor

ListDataResponse({...}): Initializes a ListDataResponse instance with various optional parameters.

Parameters:
  • List? data: A list of items of type T.
  • String? developerMessage: A message intended for developers, providing additional details about the response.
  • bool error : Indicates whether the response represents an error. Defaults to false.
  • String? message: A general message about the response, often user-facing.
  • String status: The status of the response, indicating the overall result (e.g., “success”, “error”).
  • String? pageNumber : The current page number in the paginated response.
  • String? pageSize: The number of items per page.
  • String? totalNumberOfPages: The total number of pages available.
  • String? totalNumberOfRecords : The total number of records in the dataset.

Factory Constructor

ListDataResponse.fromJson(Map<String, dynamic>? json, Function(Map<String, dynamic>?) create)

Parses a JSON object and creates a ListDataResponse instance. It uses helper functions to handle different field names and structures within the JSON object, supporting a variety of possible JSON formats for lists and pagination metadata.

Parameters:
  • Map<String, dynamic>? json: The JSON map to parse data from.
  • Function(Map<String, dynamic>?) create: A function that parses each item in data into type T.

Properties

  • List? data : Holds the primary list of items in the response.
  • String? developerMessage: Message for developers, providing extra context or debugging information.
  • bool error: Indicates if the response represents an error. Defaults to false.
  • String? message: General message describing the response, often user-facing.
  • String status: The overall response status.
  • String? pageNumber: The current page number.
  • String? pageSize: The number of items per page.
  • String? totalNumberOfPages: The total number of pages available.
  • String? totalNumberOfRecords: The total number of records in the dataset.

Methods

Map<String, dynamic> toMap()

Converts the ListDataResponse instance to a Map<String, dynamic>, useful for serialization or logging.

Returns:

Map<String, dynamic>: A map representation of the ListDataResponse, including data, developerMessage, error, message, and status.

bool isLastPage()

Determines whether the current page is the last page in the paginated response.

Returns:

bool: true if the current pageNumber is equal to or greater than totalNumberOfPages, indicating the last page; otherwise false.

Declaration:

dart
class ListDataResponse<T extends Serializable> implements Serializable {
  List<T>? data;
  String? developerMessage;
  bool error;
  String? message;
  String status;

  //page
  String? pageNumber;
  String? pageSize;
  String? totalNumberOfPages;
  String? totalNumberOfRecords;

  ListDataResponse({
    this.data,
    this.developerMessage,
    this.error = false,
    this.message,
    this.pageNumber,
    this.pageSize,
    this.totalNumberOfPages,
    this.totalNumberOfRecords,
    required this.status,
  });

  factory ListDataResponse.fromJson(
    Map<String, dynamic>? json,
    Function(Map<String, dynamic>?) create,
  ) {
    //retrievers
    dynamic retrieveData(Map<String, dynamic>? json) { }

    dynamic retrieveDeveloperMessage(Map<String, dynamic>? json) { }
  }


  @override
  Map<String, dynamic> toMap() {
    return {
      'data': data,
      'developerMessage': developerMessage,
      'error': error,
      'message': message,
      'status': status,
    };
  }

  bool isLastPage() {}
}
PrimitiveDataResponse<T>

The PrimitiveDataResponse class is a generic wrapper designed to handle API responses containing primitive data types (e.g., int, double, String, bool) as the primary data payload. It structures the response to include fields for error handling, developer messages, and status indicators. By implementing Serializable, it can be converted into a map format for easy logging, serialization, or further processing.

Type Parameter

  • T: The type parameter T represents the primitive data type contained in the data field. It allows this class to handle basic types like int, String, double, or bool while still providing a standardized structure for response metadata.

Constructor

PrimitiveDataResponse({...}):

  • Initializes a PrimitiveDataResponse instance with optional parameters.
Parameters:
  • T? data: The main response data of type T, representing a primitive type.
  • String? developerMessage : A message intended for developers, providing additional context or debugging information.
  • bool error: Indicates if an error occurred. Defaults to false.
  • String? message: A general message about the response, often user-facing.
  • String status: The status of the response, required to indicate the outcome (e.g., “success”, “error”).

Factory Constructor

PrimitiveDataResponse.fromJson(Map<String, dynamic>? json)

  • Creates a PrimitiveDataResponse instance by parsing a JSON object. It uses helper functions to handle possible variations in field names, supporting different response structures.
Parameters:
  • (Map<String, dynamic>?) json : The JSON map from which to parse data.
Properties
  • (T?) data: Holds the primary response data of type T.
  • (String?) developerMessage : Message for developers, providing additional context or debugging information.
  • (bool) error: Indicates if the response represents an error. Defaults to false.
  • (String?) message: A general message about the response, often user-facing.
  • (String) status: The overall response status (e.g., “success”, “error”).

Methods

Map<String, dynamic> toMap()

  • Converts the PrimitiveDataResponse instance to a Map<String, dynamic>, useful for serialization or logging.
Returns:

Map<String, dynamic>: A map representation of the PrimitiveDataResponse, including data, developerMessage, error, message, and status.

String toString()

  • Provides a string representation of the PrimitiveDataResponse instance for easy logging and debugging.
Returns:
  • String: A readable string format of the PrimitiveDataResponse containing all its fields.

Declaration:

dart
    class PrimitiveDataResponse<T> implements Serializable {
  T? data;
  String? developerMessage;
  bool error;
  String? message;
  String status;

  PrimitiveDataResponse({
    this.data,
    this.developerMessage,
    this.error = false,
    this.message,
    required this.status,
  });

  factory PrimitiveDataResponse.fromJson(Map<String, dynamic>? json) {  }

  @override
  Map<String, dynamic> toMap() {}

  @override
  String toString() { }
}
PrimitiveListResponse<T>

The PrimitiveListResponse class is a generic wrapper for handling API responses containing lists of primitive data types (e.g., int, double, String, bool). It provides a standardized structure for organizing response metadata, such as error status, messages, and status codes, while implementing the Serializable interface for easy conversion to a map format.

Type Parameter

  • T: The type parameter T represents each item in the data list, constrained to primitive types like int, String, double, or bool.

Constructor

PrimitiveListResponse({...}):

  • Initializes a PrimitiveListResponse instance with optional parameters.
Parameters:
  • List? data: A list of primitive data items of type T.
  • String? developerMessage : A message intended for developers, providing additional debugging or informational context.
  • bool error: Indicates if the response represents an error. Defaults to false.
  • String? message: A general message about the response, often user-facing.
  • String status : The overall status of the response, required to indicate the result (e.g., “success”, “error”).

Factory Constructor

PrimitiveListResponse.fromJson(Map<String, dynamic>? json)

  • Creates a PrimitiveListResponse instance by parsing a JSON object. It includes helper functions to retrieve data from multiple possible JSON fields, supporting flexible JSON structures for lists.
Parameters:
  • (Map<String, dynamic>?) json: The JSON map to parse data from.
Properties
  • List? data : Holds the primary list of data items of type T.
  • String? developerMessage: A message for developers, providing additional context or debugging information.
  • bool error : Indicates if the response represents an error. Defaults to false.
  • String? message : A general message about the response, often user-facing.
  • String status: The overall status of the response (e.g., “success”, “error”).

Methods

Map<String, dynamic> toMap()

  • Converts the PrimitiveListResponse instance to a Map<String, dynamic>, useful for serialization or logging.
Returns:

Map<String, dynamic>: A map representation of the PrimitiveListResponse, including data, developerMessage, error, message, and status.

Declaration:

dart
class PrimitiveListResponse<T> implements Serializable {
  List<T>? data;
  String? developerMessage;
  bool error;
  String? message;
  String status;

  PrimitiveListResponse({
    this.data,
    this.developerMessage,
    this.error = false,
    this.message,
    required this.status,
  });

  factory PrimitiveListResponse.fromJson(Map<String, dynamic>? json) {
    //retrievers
    dynamic retrieveData(Map<String, dynamic>? json) {}

  @override
  Map<String, dynamic> toMap() {}
}
}