jh_network_core

A small, business-agnostic Dio client builder for applications that need shared network defaults with repository-level overrides.

The package focuses on client assembly rather than API definitions. It works with plain Dio, Retrofit, or any library that accepts a Dio instance.

Features

  • Dynamic base URL and request headers
  • Shared configuration with repository-level overrides
  • Configurable header merge precedence
  • Provider-specific response decoding
  • Business response validation
  • Network error classification and custom messages
  • Logging hooks without a logging framework dependency
  • Custom Dio interceptor support
  • Pure Dart implementation with no Flutter dependency

Installation

dependencies:
  jh_network_core: ^0.1.0

Basic usage

import 'package:jh_network_core/jh_network_core.dart';

final factory = NetworkClientFactory(
  NetworkClientConfig(
    baseUrlProvider: () => environment.apiBaseUrl,
    headersProvider: (request) async => {
      'accept-language': localeProvider(),
      'authorization': await tokenProvider(),
    },
    networkErrorMessageProvider: (kind, error) => switch (kind) {
      NetworkErrorKind.noConnection => 'No internet connection.',
      NetworkErrorKind.timeout => 'The request timed out.',
      _ => null,
    },
  ),
);

final dio = factory.create();

Providers are evaluated for every request, so environment, locale, and authentication changes do not require rebuilding the client.

Repository-level overrides

Create clients with shared application defaults and local differences:

final loginDio = factory.create(
  overrides: NetworkClientOverrides(
    baseUrlProvider: () => environment.loginBaseUrl,
    headersProvider: (_) => {'x-api-module': 'login'},
    receiveTimeout: const Duration(seconds: 30),
  ),
);

final sportDio = factory.create(
  overrides: NetworkClientOverrides(
    baseUrlProvider: () => environment.sportBaseUrl,
    responseDataDecoder: decodeSportResponse,
    businessResponseValidator: validateSportResponse,
  ),
);

Configuration precedence is:

  1. Shared NetworkClientConfig
  2. Repository NetworkClientOverrides
  3. Per-request Dio options

Shared and repository headers are merged by key. Repository headers override shared headers. Per-request headers override the merged headers by default.

To force configured headers to override per-request values:

const NetworkClientOverrides(
  headerMergePolicy: HeaderMergePolicy.commonOverridesRequest,
);

Business responses

HTTP 200 does not always mean business success. Convert unsuccessful business responses into DioException values:

final config = NetworkClientConfig(
  baseUrlProvider: () => 'https://api.example.com',
  businessResponseValidator: (response) {
    final data = response.data;
    return data is Map<String, dynamic> && data['code'] == 0;
  },
  businessErrorMessageProvider: (response) {
    final data = response.data;
    return data is Map<String, dynamic> ? data['message'] as String? : null;
  },
);

Response decoding

Different providers can return different envelopes. Decode the response before business validation:

NetworkClientOverrides(
  responseDataDecoder: (data, request) => decodeProviderEnvelope(data),
  businessResponseValidator: (response) {
    final envelope = response.data as ProviderEnvelope;
    return envelope.success;
  },
);

Retrofit

Pass the configured Dio instance to a Retrofit-generated API:

final dio = factory.create(overrides: sportOverrides);
final api = SportApi(dio);

jh_network_core intentionally does not depend on Retrofit, state management, dependency injection, localization, or a logging framework.

Error messages

The package classifies transport and HTTP failures as NetworkErrorKind. Applications provide user-facing messages, keeping localization outside the networking package.

Additional information

Issues and feature requests are tracked on GitHub. Contributions are welcome through pull requests.

This package is distributed under the MIT License.

Libraries

jh_network_core
Configurable, business-agnostic Dio client infrastructure.