Skip to content

🚀 高级用法

对应 examples/advanced_usage/main.go,展示定制化客户端。

🎨 一图抵千言

本示例综合了认证、自定义 HTTP、错误处理、IPv4/IPv6、单字段查询等多块能力。下图以 advanced-usage 为中心,向上承接各基础示例的调用结构,向下汇入错误处理与字段渲染流程。

相关调用链可参考:NewClient · GetIPInfo · GetField · WithAPIKey · WithCustomHTTPClient · WithErrorHandler

调用结构速查

不同示例的调用链各不相同,下面用 Mermaid 分组速查,方便对照源码。

基础查询(basic-usage / lookup-specific-ip / lookup-client-ip

单字段查询(single-field

原始格式(raw-formats / jsonp

带 API Key(with-api-key

错误处理与自定义错误(error-handling / custom-error

IPv6 查询(ipv6

解析经纬度(parse-latlong

完整代码

go
package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/cyberspacesec/ipapi.co-skills/pkg/ipapi"
)

func main() {
	// 创建定制化客户端
	client := ipapi.NewClient(
		ipapi.WithAPIKey("your_api_key_here"),
		ipapi.WithCustomHTTPClient(&http.Client{
			Timeout:   15 * time.Second,
			Transport: &http.Transport{MaxIdleConns: 10},
		}),
		ipapi.WithErrorHandler(customErrorHandler),
	)

	ctx := context.Background()

	// 获取特定IP的详细信息
	printIPInfo(client, ctx, "8.8.8.8")
	printIPInfo(client, ctx, "2001:4860:4860::8888")

	// 获取特定字段
	if org, err := client.GetField(ctx, "8.8.8.8", "org"); err == nil {
		fmt.Printf("\nDNS服务器所属组织: %s\n", org)
	}
}

func printIPInfo(client *ipapi.Client, ctx context.Context, ip string) {
	info, err := client.GetIPInfo(ctx, ip, "json")
	if err != nil {
		log.Printf("查询IP %s 失败: %v", ip, err)
		return
	}

	fmt.Printf("\n%s 的详细信息:\n", ip)
	fmt.Printf("地理位置: %s, %s\n网络信息: %s (%s)\n时区: %s (UTC%s)\n",
		info.City, info.CountryName,
		info.ASN, info.Org,
		info.Timezone, info.UTCOffset)
}

func customErrorHandler(err error) error {
	fmt.Printf("\n自定义错误处理: %v\n", err)
	return err
}

要点解析

1. 组合多个选项

go
client := ipapi.NewClient(
	ipapi.WithAPIKey("your_api_key_here"),
	ipapi.WithCustomHTTPClient(...),
	ipapi.WithErrorHandler(customErrorHandler),
)

一次配齐:认证 + 自定义 HTTP + 错误处理。详见 选项函数

2. 自定义 HTTP 客户端

go
&http.Client{
	Timeout:   15 * time.Second,
	Transport: &http.Transport{MaxIdleConns: 10},
}

调长超时 + 连接池。详见 WithCustomHTTPClient

3. 自定义错误处理

go
func customErrorHandler(err error) error {
	fmt.Printf("\n自定义错误处理: %v\n", err)
	return err
}

每个错误返回前先打印。详见 WithErrorHandler

4. 同时查 IPv4 和 IPv6

go
printIPInfo(client, ctx, "8.8.8.8")
printIPInfo(client, ctx, "2001:4860:4860::8888")

SDK 对 IPv4/IPv6 透明,URL 构建内部处理冒号。

5. 单字段查询

go
org, err := client.GetField(ctx, "8.8.8.8", "org")

只拿组织名。详见 GetField

运行预期输出与常见问题

预期输出(已设置有效 API Key 时):

8.8.8.8 的详细信息:
地理位置: Mountain View, United States
网络信息: AS15169 (Google LLC)
时区: America/Los_Angeles (UTC-07:00)

2001:4860:4860::8888 的详细信息:
地理位置: Mountain View, United States
网络信息: AS15169 (Google LLC)
时区: America/Los_Angeles (UTC-07:00)

DNS服务器所属组织: Google LLC

常见问题:

  • 未设置 API Key 却频繁限流? 免费额度有限,WithAPIKey 注入 Bearer 认证可提高上限;触发限流会返回 ErrRateLimited,属可重试错误。
  • IPv6 地址带冒号,URL 会出错吗? 不会。SDK 内部 newGetRequest 已处理冒号转义,ValidateIP 也会先校验合法性。
  • 自定义 HTTP 客户端的超时被覆盖了? WithCustomHTTPClient 注入的 *http.Client 优先级最高;若未设置,SDK 用默认 Timeout
  • customErrorHandler 返回 nil 会吞掉错误吗? 不会。返回 nil 等于“消化”错误,后续 GetIPInfo 会返回 nil,需自行保证不漏报。
  • 重试策略是什么? 默认 Retries=2(最多请求 3 次),仅对网络错误与 5xx 重试;4xx(含 429)不重试。详见 IsRetryableError

运行

bash
cd examples/advanced_usage
go run main.go

预期输出:

8.8.8.8 的详细信息:
地理位置: Mountain View, United States
网络信息: AS15169 (Google LLC)
时区: America/Los_Angeles (UTC-07:00)

2001:4860:4860::8888 的详细信息:
地理位置: Mountain View, United States
网络信息: AS15169 (Google LLC)
时区: America/Los_Angeles (UTC-07:00)

DNS服务器所属组织: Google LLC

下一步

基于 MIT 许可证发布