# 服务客户端 iTi-Flask 提供同步 HTTP JSON 服务客户端。 它用于业务项目调用独立服务。 ## 能力 支持: - base URL 配置。 - service token 鉴权。 - 超时。 - 按方法和状态码重试。 - 可选熔断。 - `X-Trace-Id` 透传。 - 结构化调用日志。 - envelope 自动识别。 - HTTP status 自动识别。 - 测试用 mock transport。 不支持: - 服务发现。 - 负载均衡。 - gRPC。 - streaming。 - async client。 - OpenAPI client 生成。 ## 配置 ```python class DevConfig(BaseDevConfig): def __init__(self) -> None: super().__init__() self.services = { "inventory": { "base_url": "http://inventory.local", "token": "change-me", "timeout": { "connect": 1.0, "read": 5.0, "write": 5.0, "pool": 1.0, }, "retry": { "attempts": 2, "backoff": 0.2, "statuses": [502, 503, 504], "methods": ["GET", "HEAD", "OPTIONS"], }, "circuit_breaker": { "enabled": False, "fail_max": 5, "reset_timeout": 30, }, } } ``` `base_url` 必填。 `token` 非空时,客户端会发送: ```http Authorization: Bearer change-me ``` ## 使用 ```python from iti.service_client import service_client inventory = service_client(app, "inventory") item = inventory.get("/items/{id}", path={"id": "A001"}) created = inventory.post("/items", json={"name": "demo"}) ``` `GET`、`HEAD`、`OPTIONS` 默认可按配置重试。 `POST` 默认不重试。 需要强制重试: ```python inventory.post("/jobs", json={"kind": "sync"}, retry=True) ``` ## Trace ID 客户端会为每次调用生成 `X-Trace-Id`。 ## 错误 客户端会抛出这些异常: - `ServiceConfigError` - `ServiceUnavailableError` - `ServiceHTTPError` - `ServiceBusinessError` 响应体如果是 envelope: - `code == 200` 返回 `data`。 - `code != 200` 抛出 `ServiceBusinessError`。 这条规则不依赖 HTTP status。 也就是说,HTTP 401 + envelope `code=401` 会抛 `ServiceBusinessError`,调用方可统一处理业务 code。 非 envelope 的非 2xx 响应会抛出 `ServiceHTTPError`。 envelope 只认同时包含 `data`、`code`、`message` 的 JSON object。 响应体为空时返回 `None`。 `expect_json=False` 时返回原始 `httpx.Response`。