example-petstore.com

示例域名 · 并非真实服务 · 浏览器访问显示此页面 · API 请求返回 410 Gone

指南 · API

配置 API 客户端和 SDK

发往 api.example-petstore.com 等地址的请求,来自仍将示例地址用作基础 URL 的代码。本指南介绍该地址通常位于何处、如何将其移至配置中,以及如何防止此类问题再次发生。

从示例复制的基础 URL

  1. 您的代码 API_BASE_URL=https://api.example-petstore.com
  2. GET /v2/pet/42 Authorization: Bearer ••••
  3. 示例域名:别人的服务器 api.example-petstore.com
  4. 410 Gone 密钥落入了陌生人手中:请撤销

从配置读取的基础 URL

  1. 您的代码 API_BASE_URL=${API_BASE_URL}
  2. GET /v2/pet/42 Authorization: Bearer ••••
  3. 真实服务
  4. 200 OK 请求和密钥到达正确的服务
同一个调用的两种写法。使用从示例复制的地址时,请求及其密钥会落到您无法控制的服务器上,本域名返回 410 Gone。请改为从配置中读取地址。

您收到的响应

凡是带有请求正文、发往 /v2/pet 等 API 式路径或请求 JSON 的请求,都会收到 410 Gone 以及一份问题描述(RFC 9457):

HTTP/1.1 410 Gone
Content-Type: application/problem+json; charset=utf-8

{"type":"https://example-petstore.com/#where","title":"Example domain, not a real service",
 "status":410,"detail":"api.example-petstore.com is an example domain used in documentation. …"}

此域名并非 Swagger Petstore 示例 API,后者位于 petstore.swagger.io。

地址所在的位置

  • 代码中的常量或默认值(BASE_URL = "https://api.example-petstore.com");
  • 从示例中复制的配置文件、.env 文件或环境变量;
  • 用于生成客户端的 OpenAPI 描述中的 host 或 servers 字段;
  • Postman 或 Insomnia 的环境变量,例如 {{baseUrl}};
  • 针对占位地址运行的测试、测试夹具和 CI 作业。

正确配置

从配置中读取地址,并在缺少该地址时明确报错:

# Python: read the address from configuration, not from the code
import os
BASE_URL = os.environ["API_BASE_URL"]

// JavaScript / Node.js
const baseURL = process.env.API_BASE_URL;

// PHP 8
$baseUrl = getenv('API_BASE_URL') ?: throw new RuntimeException('API_BASE_URL is not set');
# Python, httpx
client = httpx.Client(base_url=os.environ["API_BASE_URL"])

// Node.js, axios
const api = axios.create({ baseURL: process.env.API_BASE_URL });

# Generated OpenAPI client (Python)
configuration = Configuration(host=os.environ["API_BASE_URL"])

// PHP, Guzzle
$client = new GuzzleHttp\Client(['base_uri' => getenv('API_BASE_URL')]);

// PHP, Symfony HttpClient
$client = Symfony\Component\HttpClient\HttpClient::createForBaseUri(getenv('API_BASE_URL'));

在 Postman 或 Insomnia 中,请为每个环境分别设置 baseUrl,并在发送请求前选择正确的环境。

预防措施

添加一项启动检查或测试检查,拒绝示例地址:

# Python
import os, re
base = os.environ["API_BASE_URL"]
if re.search(r"example-(petstore|commerce-host)\.com", base):
    raise RuntimeError(f"API_BASE_URL still points at an example domain: {base}")

// PHP
$base = getenv('API_BASE_URL') ?: '';
if (preg_match('/example-(petstore|commerce-host)\.com/', $base)) {
    throw new RuntimeException("API_BASE_URL still points at an example domain: $base");
}

在您自己的文档和示例中,请使用专为此用途保留的名称,例如 api.example.com。请参阅示例域名。

已发送的密钥

如果请求中携带了 API 密钥、令牌、密码或会话 Cookie,那么它们已被发送到错误的服务器。请在签发它们的服务中将其撤销,并签发新的凭据。凭据泄露:现在该怎么办。

不依赖真实服务进行测试: 用 Mock API 测试,而不是示例地址

来源