flutter_api_inspector 0.2.0 copy "flutter_api_inspector: ^0.2.0" to clipboard
flutter_api_inspector: ^0.2.0 copied to clipboard

Manual API instrumentation and a debug-only in-app overlay timeline for Flutter. Developers call ApiTrace.call(name, …, execute: …) at the call site; the package records each call into an in-memory ri [...]

example/lib/main.dart

// Example app for the flutter_api_inspector package.
//
// This app demonstrates manual API instrumentation via [ApiTrace.call].
// Two buttons are exposed:
//
//   * **Run stub call** — synchronous, returns a fake [ApiTraceResponse]
//     with `statusCode == 200`. Works offline and is deterministic in
//     both debug and release builds.
//   * **Run real call to httpbin** — one real call to
//     `https://httpbin.org/get` using `dart:io`'s [HttpClient]
//     directly (no `package:http`, no `package:dio`). The button is
//     gated by [kDebugMode] and is hidden in release builds so the
//     example is deterministic offline.
//
// The app is wrapped with [ApiTrace.runApp] so the debug-only
// overlay (floating action button + timeline panel + detail screen)
// mounts automatically under [kDebugMode].
//
// Run: `flutter run` from the `example/` directory.

import 'dart:io' show HttpClient;

import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart';
import 'package:flutter_api_inspector/flutter_api_inspector.dart';

void main() => ApiTrace.runApp(const ExampleApp());

/// The root [MaterialApp] of the example.
///
/// The home screen ([_ExampleHome]) exposes the two trace buttons.
class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter_api_inspector example',
      theme: ThemeData(
        colorSchemeSeed: Colors.indigo,
        useMaterial3: true,
      ),
      home: const _ExampleHome(),
    );
  }
}

class _ExampleHome extends StatelessWidget {
  const _ExampleHome();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('flutter_api_inspector example'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            const Padding(
              padding: EdgeInsets.all(16),
              child: Text(
                'Tap a button to record an API call.\n'
                'The debug-only overlay (FAB) appears automatically in debug builds.',
                textAlign: TextAlign.center,
              ),
            ),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              key: const Key('stub-button'),
              icon: const Icon(Icons.bug_report),
              label: const Text('Run stub call'),
              onPressed: () => _runStubCall(context),
            ),
            const SizedBox(height: 12),
            // The Real button is hidden in release builds. The
            // kDebugMode gate keeps the example deterministic
            // offline (per the task brief: "gated by kDebugMode").
            if (kDebugMode) ...<Widget>[
              ElevatedButton.icon(
                key: const Key('real-button'),
                icon: const Icon(Icons.cloud),
                label: const Text('Run real call to httpbin'),
                onPressed: () => _runRealCall(context),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Future<void> _runStubCall(BuildContext context) async {
    final messenger = ScaffoldMessenger.of(context);
    final id = await ApiTrace.call(
      'stub',
      method: 'GET',
      url: Uri.parse('https://example.com/stub'),
      // The default config (details: {minimal, response}) applies:
      // status, duration, and the response body are recorded. The
      // stub returns no body, so only status/duration show up.
      // The id is returned so the call site can correlate logs.
      execute: () async {
        return const ApiTraceResponse(statusCode: 200);
      },
    );
    messenger.showSnackBar(
      SnackBar(content: Text('Stub call recorded: id=$id')),
    );
  }

  Future<void> _runRealCall(BuildContext context) async {
    final messenger = ScaffoldMessenger.of(context);
    final id = await ApiTrace.call(
      'httpbin.get',
      method: 'GET',
      url: Uri.parse('https://httpbin.org/get'),
      // Widen the capture to {headers, response} so the overlay
      // shows the response body and headers for this one call only.
      detailOverride: const <ApiTraceDetail>{
        ApiTraceDetail.headers,
        ApiTraceDetail.response,
      },
      execute: () async {
        // Use dart:io's HttpClient directly — no package:http,
        // no package:dio (per AGENTS.md rule 7).
        final client = HttpClient();
        try {
          final request = await client.getUrl(
            Uri.parse('https://httpbin.org/get'),
          );
          final response = await request.close();
          // Drain the response body so the connection is released
          // back to the pool. We don't surface the body in the
          // captured response (the package truncates to the
          // configured maxResponseBodyBytes); the example just
          // wants the status code.
          await response.drain<void>();
          return ApiTraceResponse(
            statusCode: response.statusCode,
          );
        } finally {
          client.close(force: true);
        }
      },
    );
    messenger.showSnackBar(
      SnackBar(content: Text('Real call recorded: id=$id')),
    );
  }
}
1
likes
0
points
314
downloads

Publisher

unverified uploader

Weekly Downloads

Manual API instrumentation and a debug-only in-app overlay timeline for Flutter. Developers call ApiTrace.call(name, …, execute: …) at the call site; the package records each call into an in-memory ring buffer and renders a floating action button plus panel that lists calls in chronological order with status, duration, and captured request / response fields. The overlay is guarded by kDebugMode and tree-shaken from flutter build --release binaries.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

dio, flutter

More

Packages that depend on flutter_api_inspector