home / skills / hoangnguyen0403 / agent-skills-standard / retrofit-networking

retrofit-networking skill

/skills/flutter/retrofit-networking

This skill helps you implement type-safe REST calls in Flutter using Retrofit and Dio with auth interceptors, token refresh, and robust error handling.

npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill retrofit-networking

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
2.1 KB
---
name: Flutter Networking (Retrofit & Dio)
description: HTTP networking standards using Dio and Retrofit with Auth interceptors.
metadata:
  labels: [networking, retrofit, dio]
  triggers:
    files: ['**/data_sources/**', '**/api/**']
    keywords: [Retrofit, Dio, RestClient, GET, POST, Interceptor, refreshing]
---

# Retrofit & Dio Networking

## **Priority: P0 (CRITICAL)**

Type-safe REST API communication using `Dio` and `Retrofit`.

## Structure

```text
infrastructure/
├── data_sources/
│   ├── remote/ # Retrofit abstract classes
│   └── local/ # Cache/Storage
└── network/
    ├── dio_client.dart # Custom Dio setup
    └── interceptors/ # Auth, Logging, Cache
```

## Implementation Guidelines

- **Retrofit Clients**: Define abstract classes with `@RestApi()`. Use standard HTTP annotations (`@GET`, `@POST`).
- **DTOs (Data Transfer Objects)**: Use `@freezed` and `json_serializable` for all response/request bodies.
- **Mapping**: Data sources MUST map DTOs to Domain Entities (e.g., `userDto.toDomain()`).
- **Safe Enums**: Always use `@JsonKey(unknownEnumValue: ...)` for DTO enums to prevent crashes when the backend introduces new values.
- **AuthInterceptor**: Logic for `Authorization: Bearer <token>` injection in `onRequest`.
- **Token Refresh**: Handle `401 Unauthorized` in `onError` by locking Dio, refreshing, and retrying.
- **Failures**: Map `DioException` to custom `Failure` objects (ServerFailure, NetworkFailure).

## Anti-Patterns

- **No Manual JSON Parsing**: Do not use `jsonDecode(response.body)`; use Retrofit's generated mappers.
- **No Global Dio**: Do not use a static global Dio instance; use dependency injection.
- **No Try-Catch in API**: Do not put `try-catch` inside the Retrofit interface methods.
- **No Unsafe Enums**: Do not leave enums in DTOs without handling unknown values from the server.

## Reference & Examples

For RestClient definitions and Auth Interceptor implementation:
See [references/REFERENCE.md](references/REFERENCE.md).

## Related Topics

feature-based-clean-architecture | error-handling

Overview

This skill codifies production-ready HTTP networking patterns for Flutter using Dio and Retrofit. It enforces type-safe REST clients, DTO-to-domain mapping, and robust auth handling with interceptors and token refresh. The goal is predictable, testable networking that avoids common runtime failures and anti-patterns.

How this skill works

The skill defines a clear folder structure: remote Retrofit abstracts, local caches, and a custom Dio client with interceptors. Retrofit generates request/response mappers while DTOs use freezed + json_serializable to ensure immutability and safe JSON. An AuthInterceptor injects Authorization headers, handles 401s by locking Dio, performing token refresh, and replaying requests. DioExceptions are translated into domain Failures for consistent error handling.

When to use it

  • Building any Flutter app that talks to REST APIs and needs type safety and maintainability
  • When you require automatic request/response mapping with Retrofit codegen
  • When token-based authentication and automated refresh/retry are needed
  • When you want clear separation between DTOs and domain entities
  • When you need consistent, testable error handling for network layers

Best practices

  • Define Retrofit clients as abstract classes with @RestApi and HTTP annotations (@GET, @POST, etc.).
  • Use @freezed and json_serializable for all DTOs and provide toDomain()/fromDomain() mappers.
  • Always annotate enums with @JsonKey(unknownEnumValue: ...) to avoid crashes from unexpected server values.
  • Implement an AuthInterceptor to inject Bearer tokens in onRequest and handle 401 in onError by locking Dio, refreshing tokens, then retrying the original request.
  • Map DioException instances to custom Failure types (ServerFailure, NetworkFailure) at the data source boundary.
  • Provide Dio via dependency injection; avoid global or static Dio instances.

Example use cases

  • User authentication flow: login returns tokens, interceptor injects Authorization, refresh logic handles expired tokens transparently.
  • Feature-based clean architecture: each feature has infrastructure/data_sources/remote and maps DTOs to feature domain models.
  • Offline-first caching: local data_sources/cache used when network calls fail, with consistent Failure mapping.
  • Third-party API integration: Retrofit interfaces with generated serializers and safe enums to prevent runtime crashes.

FAQ

How should I handle enum values added by the backend?

Annotate DTO enums with @JsonKey(unknownEnumValue: <fallback>) so unknown values map to a safe default instead of throwing.

Where do I map network DTOs to domain models?

Map DTOs inside the data source layer (remote) or a dedicated mapper so Retrofit-generated classes remain separate from domain entities.

Should I catch exceptions inside Retrofit interfaces?

No. Let Retrofit and Dio propagate errors. Catch and translate DioException into Failure objects at the data source boundary.