패키지, 저장소 및 앱 카테고리 검색

패키지 상세v3.3.1

dio_http_formatter

HTTP 요청/응답을 콘솔에 보기 쉽게 출력하기 위한 Dio 인터셉터

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
3.2천
좋아요
51
Pub 점수
130

패키지 설치

flutter pub add dio_http_formatter

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Dio 인터셉터로 HTTP 요청과 응답을 콘솔에 명확한 형식으로 예쁘게 출력하여 디버깅을 향상시킵니다. 개발 중 데이터 흐름, 헤더, 상태 코드를 빠르게 확인할 수 있도록 도와줍니다. 이 패키지는 인기 있는 Dart용 HTTP 클라이언트인 Dio와 원활하게 통합되며, Android, iOS, Web, macOS, Windows, Linux 등 주요 플랫폼을 모두 지원합니다. 외부 도구 없이 API 상호작용 문제를 진단하는 데 이상적입니다.

사용 사례

  • 개발 중 API 호출 디버깅
  • 요청/응답 페이로드 검사
  • HTTP 헤더 및 상태 코드 모니터링
  • API 통합 중 개발자 생산성 향상
  • 네트워크 활동의 실시간 로깅

주요 기능

  • 포맷팅된 JSON 출력
  • 요청과 응답 둘 다 지원
  • Dio와의 간편한 통합
  • 크로스 플랫폼 호환성
  • 사용자 정의 가능한 로깅 레벨
  • 최소한의 설정 필요

적합한 대상

  • Dio를 사용하는 프론트엔드 개발자
  • 빠른 API 디버깅에 집중하는 팀
  • 투명한 네트워크 검사가 필요한 응용 프로그램
  • RESTful 서비스를 개발하는 개발자
  • 실시간 콘솔 로그가 유용한 프로젝트

고려 사항

  • 생산 빌드에 권장되지 않습니다
  • 로깅으로 인해 성능에 약간의 영향을 줄 수 있습니다
  • 릴리스 모드에서 비활성화하려면 수동 구성이 필요합니다
  • 필터링되지 않은 경우 로그는 민감한 데이터를 노출할 수 있습니다
  • 콘솔 출력만 가능하며, 파일 또는 외부 로깅 지원 없음

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Pub Version

A simple Dio interceptor for pretty printing the HTTP request/response (using the awesome package Logger) to be printed in the console for easier debugging and sharing.

Different content types are supported and pretty printed such as:

  • application/json
  • application/x-www-form-urlencoded
  • text/html

Getting started

1- Install the package in your project:

flutter pub get dio_http_formatter

or if not for Flutter:

pub get dio_http_formatter

2- Add the interceptor to your Dio instance like:


final _dio = Dio();
_dio.interceptors.add(HttpFormatter());
Dio Version Map

For a certain version of Dio, use the following table to find the correct version of this package to use:

Dio Version Package Version
4.x.x 2.x.x
5.x.x 3.x.x

Options

Below are the optional parameters that can be specified for the formatter to customize what and how the HTTP request and response is printed.

Property Type Default Value
includeRequest bool true
includeRequestHeaders bool true
includeRequestQueryParams bool true
includeRequestBody bool true
includeResponse bool true
includeResponseHeaders bool true
includeResponseBody bool true
logger Logger PrettyPrinter()
loggingFilter LoggingFilter null

Logging Filter

The HTTPFormatter has support for filtering whether to log a request/response or not. For example:


final dio = Dio();
dio.interceptors.add(
  HttpFormatter(
    loggingFilter: (request, response, error) {
      // We don't want to print the request/response when 201 is returned
      if (response?.statusCode == 201) {
        return false;
      }
      // Otherwise, the logs should print
      return true;
    },
  ),
);

[!WARNING]
httpLoggerFilter is now deprecated and it's highly encouraged to move to the new loggingFilter. httpLoggerFilter will be removed in the next major version.

Examples

POST request [application/json]
  await _dio.post('https://postman-echo.com/post',
      data: <String, dynamic>{'foo': 'foo'},
      options: Options()
        ..headers = <String, dynamic>{
          'my-custom-header': 'my-custom-header',
          'content-type': 'application/json'
        });
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ ⤴ REQUEST ⤴
│ 
│ POST https://postman-echo.com/post
│ content-type: application/json
│ my-custom-header: my-custom-header
│ content-length: 13
│ 
│ 
│ {
│   "foo": "foo"
│ }
│ 
│ ⤵ RESPONSE [200/OK] [Time elapsed: 1080 ms]⤵
│ 
│ connection: [keep-alive]
│ set-cookie: [sails.sid=s%3AlO2moZlJ_-LGJZdq_o0KRpliqamhCecq.lNnUP5X%2Fvr%2BXi2an7q6GJki9DPmDQyPAyBW7p117ijM; Path=/; HttpOnly]
│ date: [Mon, 22 Jun 2020 17:29:07 GMT]
│ vary: [Accept-Encoding]
│ content-length: [417]
│ etag: [W/"1a1-14yzanqIFzi16qAA3YVbkp9Acl8"]
│ content-type: [application/json; charset=utf-8]
│ 
│ 
│ {
│   "args": {},
│   "data": {
│     "foo": "foo"
│   },
│   "files": {},
│   "form": {},
│   "headers": {
│     "x-forwarded-proto": "https",
│     "x-forwarded-port": "443",
│     "host": "postman-echo.com",
│     "x-amzn-trace-id": "Root=1-5ef0ea63-50bc2440e0e07883458a067f",
│     "content-length": "13",
│     "user-agent": "Dart/2.8 (dart:io)",
│     "content-type": "application/json",
│     "my-custom-header": "my-custom-header",
│     "accept-encoding": "gzip"
│   },
│   "json": {
│     "foo": "foo"
│   },
│   "url": "https://postman-echo.com/post"
│ }
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
POST request [multipart/form-data]
await dio.post(
    "https://postman-echo.com/post",
    data: FormData.fromMap({
      "foo": "foo",
      "bar": MultipartFile.fromBytes([1, 2, 3, 4, 5, 6])
    }),
  );
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ ⤴ REQUEST ⤴
│ 
│ POST https://postman-echo.com/post
│ content-type: multipart/form-data; boundary=--dio-boundary-0846883596
│ content-length: 234
│ 
│ 
│ {
│   "foo": "foo",
│   "bar": "[application/octet-stream; length=6]"
│ }
│ 
│ ⤵ RESPONSE [200/OK] [Time elapsed: 1431 ms]⤵
│ 
│ etag: [W/"238-Drbr+mbesAC7mnUT1/6HdwqJbOg"]
│ connection: [keep-alive]
│ content-type: [application/json; charset=utf-8]
│ set-cookie: [sails.sid=s%3AYZPFhMKwqVTkLbZkRSbdqY_ZGZYFul8h.UrGXXLdzjfYJEdEVOlpQND2Ms3KnpKomTNQh42u3tS4; Path=/; HttpOnly]
│ date: [Sun, 19 Mar 2023 12:39:21 GMT]
│ content-length: [568]
│ 
│ 
│ {
│   "args": {},
│   "data": {},
│   "files": {
│     "undefined": "data:application/octet-stream;base64,AQIDBAUG"
│   },
│   "form": {
│     "foo": "foo"
│   },
│   "headers": {
│     "x-forwarded-proto": "https",
│     "x-forwarded-port": "443",
│     "host": "postman-echo.com",
│     "x-amzn-trace-id": "Root=1-64170279-48f590a477b666d63975dd13",
│     "content-length": "234",
│     "user-agent": "Dart/2.19 (dart:io)",
│     "content-type": "multipart/form-data; boundary=--dio-boundary-0846883596",
│     "accept-encoding": "gzip"
│   },
│   "json": null,
│   "url": "https://postman-echo.com/post"
│ }
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
POST request [application/x-www-form-urlencoded]
await dio.post(
    "https://postman-echo.com/post",
    data: {
      "foo": "foo",
      "bar": "bar",
    },
    options: Options(
      contentType: Headers.formUrlEncodedContentType,
    ),
  );
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ ⤴ REQUEST ⤴
│ 
│ POST https://postman-echo.com/post
│ content-type: application/x-www-form-urlencoded
│ content-length: 15
│ 
│ 
│ {
│   "foo": "foo",
│   "bar": "bar"
│ }
│ 
│ ⤵ RESPONSE [200/OK] [Time elapsed: 1419 ms]⤵
│ 
│ etag: [W/"213-RckysDJgyaHU3rsP8vCoDnqI4Pg"]
│ connection: [keep-alive]
│ content-type: [application/json; charset=utf-8]
│ set-cookie: [sails.sid=s%3AxDq5jvVLfuAkxh5o0pUhZOLzkqPt4xBz.apV3a%2FKrhiKWA%2B7foUqihO0BMGTnCOwVSiiW93CBozo; Path=/; HttpOnly]
│ date: [Sun, 19 Mar 2023 12:42:13 GMT]
│ content-length: [531]
│ 
│ 
│ {
│   "args": {},
│   "data": "",
│   "files": {},
│   "form": {
│     "foo": "foo",
│     "bar": "bar"
│   },
│   "headers": {
│     "x-forwarded-proto": "https",
│     "x-forwarded-port": "443",
│     "host": "postman-echo.com",
│     "x-amzn-trace-id": "Root=1-64170325-433157c952cf5ed84f36f867",
│     "content-length": "15",
│     "user-agent": "Dart/2.19 (dart:io)",
│     "content-type": "application/x-www-form-urlencoded",
│     "accept-encoding": "gzip"
│   },
│   "json": {
│     "foo": "foo",
│     "bar": "bar"
│   },
│   "url": "https://postman-echo.com/post"
│ }
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Successful GET request [text/html]
await _dio.get('https://example.org');
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ ⤴ REQUEST ⤴
│ 
│ GET https://example.org
│ 
│ 
│ ⤵ RESPONSE [200/OK] [Time elapsed: 963 ms]⤵
│ 
│ cache-control: [max-age=604800]
│ last-modified: [Thu, 17 Oct 2019 07:18:26 GMT]
│ date: [Mon, 22 Jun 2020 17:34:41 GMT]
│ content-encoding: [gzip]
│ vary: [Accept-Encoding]
│ age: [336678]
│ content-type: [text/html; charset=UTF-8]
│ server: [ECS (dcb/7FA3)]
│ accept-ranges: [bytes]
│ content-length: [648]
│ etag: ["3147526947"]
│ x-cache: [HIT]
│ expires: [Mon, 29 Jun 2020 17:34:41 GMT]
│ 
│ 
│ <!doctype html>
│ <html>
│ <head>
│     <title>Example Domain</title>
│ 
│     <meta charset="utf-8" />
│     <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
│     <meta name="viewport" content="width=device-width, initial-scale=1" />
│     <style type="text/css">
│     body {
│         background-color: #f0f0f2;
│         margin: 0;
│         padding: 0;
│         font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
│         
│     }
│     div {
│         width: 600px;
│         margin: 5em auto;
│         padding: 2em;
│         background-color: #fdfdff;
│         border-radius: 0.5em;
│         box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
│     }
│     a:link, a:visited {
│         color: #38488f;
│         text-decoration: none;
│     }
│     @media (max-width: 700px) {
│         div {
│             margin: 0 auto;
│             width: auto;
│         }
│     }
│     </style>    
│ </head>
│ 
│ <body>
│ <div>
│     <h1>Example Domain</h1>
│     <p>This domain is for use in illustrative examples in documents. You may use this
│     domain in literature without prior coordination or asking for permission.</p>
│     <p><a href="https://www.iana.org/domains/example">More information...</a></p>
│ </div>
│ </body>
│ </html>
│ 
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Successful GET request with Query Params [text/html]
  await _dio.get('https://example.com',
        queryParameters: {'limit_start': 0, 'search_term': 'dart'});
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ ⤴ REQUEST ⤴
│ 
│ GET https://example.com
│ 
│ ===== Query Parameters =====
│ limit_start : 0
│ search_term : dart
│ 
│ ⤵ RESPONSE [200/OK] [Time elapsed: 1204 ms]⤵
│ 
│ last-modified: [Thu, 17 Oct 2019 07:18:26 GMT]
│ cache-control: [max-age=604800]
│ date: [Fri, 26 Nov 2021 12:04:26 GMT]
│ vary: [Accept-Encoding]
│ content-encoding: [gzip]
│ content-length: [648]
│ age: [86638]
│ etag: ["3147526947+gzip"]
│ content-type: [text/html; charset=UTF-8]
│ x-cache: [HIT]
│ server: [ECS (oxr/8317)]
│ expires: [Fri, 03 Dec 2021 12:04:26 GMT]
│ 
│ 
│ <!doctype html>
│ <html>
│ <head>
│     <title>Example Domain</title>
│ 
│     <meta charset="utf-8" />
│     <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
│     <meta name="viewport" content="width=device-width, initial-scale=1" />
│     <style type="text/css">
│     body {
│         background-color: #f0f0f2;
│         margin: 0;
│         padding: 0;
│         font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
│         
│     }
│     div {
│         width: 600px;
│         margin: 5em auto;
│         padding: 2em;
│         background-color: #fdfdff;
│         border-radius: 0.5em;
│         box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
│     }
│     a:link, a:visited {
│         color: #38488f;
│         text-decoration: none;
│     }
│     @media (max-width: 700px) {
│         div {
│             margin: 0 auto;
│             width: auto;
│         }
│     }
│     </style>    
│ </head>
│ 
│ <body>
│ <div>
│     <h1>Example Domain</h1>
│     <p>This domain is for use in illustrative examples in documents. You may use this
│     domain in literature without prior coordination or asking for permission.</p>
│     <p><a href="https://www.iana.org/domains/example">More information...</a></p>
│ </div>
│ </body>
│ </html>
│ 
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

카테고리

의존성

의존성 목록 2 개

소스 저장소

이 패키지를 사용하는 프로젝트