Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

0x0E OpenAPI Integration

🇺🇸 English    |    🇨🇳 中文

🇺🇸 English

📦 Code Changes: View Diff


1. Overview

1.1 Why OpenAPI?

Programmatic traders need API documentation to integrate with our exchange. Instead of maintaining separate docs that drift from code, we auto-generate OpenAPI 3.0 spec directly from Rust types.

1.2 Goal

  1. Serve interactive API docs at /docs (Swagger UI)
  2. Export openapi.json for SDK generation
  3. Keep docs in sync with code (single source of truth)

1.3 Key Concepts

TermDefinition
OpenAPIIndustry-standard API specification format (formerly Swagger)
utoipaRust crate for compile-time OpenAPI generation
Swagger UIInteractive API documentation interface
Code-FirstGenerate spec from code, not YAML files

1.4 Architecture Overview

┌─────────── OpenAPI Integration Flow ────────────┐
│                                                  │
│  Rust Handlers ──▶ #[utoipa::path] ──▶ OpenAPI   │
│       │                                   │      │
│       │                                   ▼      │
│       │                            Swagger UI    │
│       │                            (/docs)       │
│       │                                   │      │
│       ▼                                   ▼      │
│  Type-Safe API ◀─────────────────▶ openapi.json │
│                                          │      │
│                                          ▼      │
│                                    SDK Clients  │
│                                  (Python, TS)   │
└─────────────────────────────────────────────────┘

2. Implementation

2.1 Adding Dependencies

Cargo.toml:

[dependencies]
+ utoipa = { version = "5.3", features = ["axum_extras", "chrono", "uuid"] }
+ utoipa-swagger-ui = { version = "8.0", features = ["axum"] }

2.2 Creating OpenAPI Module

Create src/gateway/openapi.rs:

#![allow(unused)]
fn main() {
use utoipa::OpenApi;

#[derive(OpenApi)]
#[openapi(
    info(
        title = "Zero X Infinity Exchange API",
        version = "1.0.0",
        description = "High-performance crypto exchange API (1.3M orders/sec)"
    ),
    paths(
        handlers::health_check,
        handlers::get_depth,
        handlers::get_klines,
        // ... all API handlers
    ),
    components(schemas(
        types::ApiResponse<()>,
        types::DepthApiData,
        // ... all response types
    ))
)]
pub struct ApiDoc;
}

2.3 Annotating Handlers

Add #[utoipa::path] to each handler:

+ #[utoipa::path(
+     get,
+     path = "/api/v1/public/depth",
+     params(
+         ("symbol" = String, Query, description = "Trading pair"),
+         ("limit" = Option<u32>, Query, description = "Depth levels")
+     ),
+     responses(
+         (status = 200, description = "Order book depth", body = ApiResponse<DepthApiData>)
+     ),
+     tag = "Market Data"
+ )]
  pub async fn get_depth(
      State(state): State<Arc<AppState>>,
      Query(params): Query<HashMap<String, String>>,
  ) -> impl IntoResponse {
      // ... existing implementation ...
  }

2.4 Adding Schema Derivations

Add ToSchema to response types:

+ use utoipa::ToSchema;

- #[derive(Serialize, Deserialize)]
+ #[derive(Serialize, Deserialize, ToSchema)]
  pub struct DepthApiData {
+     #[schema(example = "BTC_USDT")]
      pub symbol: String,
+     #[schema(example = json!([["85000.00", "0.5"]]))]
      pub bids: Vec<[String; 2]>,
+     #[schema(example = json!([["85001.00", "0.3"]]))]
      pub asks: Vec<[String; 2]>,
  }

2.5 Integrating Swagger UI

In src/gateway/mod.rs:

+ use utoipa_swagger_ui::SwaggerUi;
+ use crate::gateway::openapi::ApiDoc;

  let app = Router::new()
      .route("/api/v1/health", get(handlers::health_check))
      .nest("/api/v1/public", public_routes)
      .nest("/api/v1/private", private_routes)
+     .merge(
+         SwaggerUi::new("/docs")
+             .url("/api-docs/openapi.json", ApiDoc::openapi())
+     )
      .with_state(state);

3. API Endpoints

3.1 Public Endpoints (No Auth)

EndpointMethodDescription
/api/v1/healthGETHealth check
/api/v1/public/depthGETOrder book depth
/api/v1/public/klinesGETK-line data
/api/v1/public/assetsGETAsset list
/api/v1/public/symbolsGETTrading pairs
/api/v1/public/exchange_infoGETExchange metadata

3.2 Private Endpoints (Ed25519 Auth)

EndpointMethodDescription
/api/v1/private/orderPOSTCreate order
/api/v1/private/cancelPOSTCancel order
/api/v1/private/ordersGETQuery orders
/api/v1/private/tradesGETTrade history
/api/v1/private/balancesGETBalance query
/api/v1/private/balances/allGETAll balances
/api/v1/private/transferPOSTInternal transfer
/api/v1/private/transfer/{id}GETTransfer status

4. SDK Generation

4.1 Python SDK

Auto-generated Python client with Ed25519 signing:

from zero_x_infinity_sdk import ZeroXInfinityClient

client = ZeroXInfinityClient(
    api_key="your_api_key",
    secret_key_bytes=secret_key  # Ed25519 private key
)

# Create order
order = client.create_order(
    symbol="BTC_USDT",
    side="BUY",
    price="85000.00",
    qty="0.001"
)

4.2 TypeScript SDK

import { ZeroXInfinityClient } from './zero_x_infinity_sdk';

const client = new ZeroXInfinityClient(apiKey, secretKey);
const depth = await client.getDepth('BTC_USDT');

5. Verification

5.1 Access Swagger UI

cargo run --release -- --gateway --port 8080
# Open: http://localhost:8080/docs

5.2 Test Results

Test CategoryTestsResult
Unit Tests293✅ All pass
Public Endpoints6✅ All pass
Private Endpoints9✅ All pass
E2E Total17✅ All pass

6. Summary

In this chapter, we added OpenAPI documentation to our trading engine:

AchievementResult
Swagger UIAvailable at /docs
OpenAPI Spec15 endpoints documented
Python SDKAuto-generated with Ed25519
TypeScript SDKType-safe client
Zero Breaking ChangesAll existing tests pass

Next Chapter: With resilience (0x0D) and documentation (0x0E) complete, the foundation is solid. The next logical step is 0x0F: Deposit & Withdraw—connecting to blockchain for real crypto funding.




🇨🇳 中文

📦 代码变更: 查看 Diff


1. 概述

1.1 为什么需要 OpenAPI?

程序化交易者需要 API 文档。与其手写 YAML 文档(容易和代码不同步),不如直接从 Rust 类型生成 OpenAPI 3.0 规范。

1.2 目标

  1. /docs 提供交互式文档(Swagger UI)
  2. 导出 openapi.json 用于 SDK 生成
  3. 文档和代码保持同步(单一事实来源)

1.3 核心概念

术语定义
OpenAPI行业标准的 API 规范格式(前身是 Swagger)
utoipaRust 编译时 OpenAPI 生成库
Swagger UI交互式 API 文档界面
代码优先从代码生成规范,而非 YAML 文件

1.4 架构总览

┌─────────── OpenAPI 集成流程 ────────────┐
│                                          │
│  Rust Handlers ──▶ #[utoipa::path] ──▶ OpenAPI
│       │                                   │
│       │                                   ▼
│       │                            Swagger UI
│       │                            (/docs)
│       ▼                                   │
│  类型安全 API ◀────────────────▶ openapi.json
│                                          │
│                                          ▼
│                                    SDK 客户端
│                                  (Python, TS)
└──────────────────────────────────────────┘

2. 实现

2.1 添加依赖

Cargo.toml:

[dependencies]
+ utoipa = { version = "5.3", features = ["axum_extras", "chrono", "uuid"] }
+ utoipa-swagger-ui = { version = "8.0", features = ["axum"] }

2.2 创建 OpenAPI 模块

创建 src/gateway/openapi.rs

#![allow(unused)]
fn main() {
use utoipa::OpenApi;

#[derive(OpenApi)]
#[openapi(
    info(
        title = "Zero X Infinity Exchange API",
        version = "1.0.0",
        description = "高性能加密货币交易所 API (1.3M 订单/秒)"
    ),
    paths(
        handlers::health_check,
        handlers::get_depth,
        handlers::get_klines,
        // ... 所有 API handlers
    ),
    components(schemas(
        types::ApiResponse<()>,
        types::DepthApiData,
        // ... 所有响应类型
    ))
)]
pub struct ApiDoc;
}

2.3 注解 Handlers

为每个 handler 添加 #[utoipa::path]

+ #[utoipa::path(
+     get,
+     path = "/api/v1/public/depth",
+     params(
+         ("symbol" = String, Query, description = "交易对"),
+         ("limit" = Option<u32>, Query, description = "深度层数")
+     ),
+     responses(
+         (status = 200, description = "订单簿深度", body = ApiResponse<DepthApiData>)
+     ),
+     tag = "行情数据"
+ )]
  pub async fn get_depth(
      State(state): State<Arc<AppState>>,
      Query(params): Query<HashMap<String, String>>,
  ) -> impl IntoResponse {
      // ... 现有实现 ...
  }

2.4 添加 Schema 派生

为响应类型添加 ToSchema

+ use utoipa::ToSchema;

- #[derive(Serialize, Deserialize)]
+ #[derive(Serialize, Deserialize, ToSchema)]
  pub struct DepthApiData {
+     #[schema(example = "BTC_USDT")]
      pub symbol: String,
+     #[schema(example = json!([["85000.00", "0.5"]]))]
      pub bids: Vec<[String; 2]>,
+     #[schema(example = json!([["85001.00", "0.3"]]))]
      pub asks: Vec<[String; 2]>,
  }

2.5 集成 Swagger UI

src/gateway/mod.rs 中:

+ use utoipa_swagger_ui::SwaggerUi;
+ use crate::gateway::openapi::ApiDoc;

  let app = Router::new()
      .route("/api/v1/health", get(handlers::health_check))
      .nest("/api/v1/public", public_routes)
      .nest("/api/v1/private", private_routes)
+     .merge(
+         SwaggerUi::new("/docs")
+             .url("/api-docs/openapi.json", ApiDoc::openapi())
+     )
      .with_state(state);

3. API 端点

3.1 公开端点(无需认证)

端点方法描述
/api/v1/healthGET健康检查
/api/v1/public/depthGET订单簿深度
/api/v1/public/klinesGETK 线数据
/api/v1/public/assetsGET资产列表
/api/v1/public/symbolsGET交易对
/api/v1/public/exchange_infoGET交易所信息

3.2 私有端点(Ed25519 认证)

端点方法描述
/api/v1/private/orderPOST创建订单
/api/v1/private/cancelPOST取消订单
/api/v1/private/ordersGET查询订单
/api/v1/private/tradesGET成交历史
/api/v1/private/balancesGET余额查询
/api/v1/private/balances/allGET所有余额
/api/v1/private/transferPOST内部划转
/api/v1/private/transfer/{id}GET划转状态

4. SDK 生成

4.1 Python SDK

自动生成的 Python 客户端(含 Ed25519 签名):

from zero_x_infinity_sdk import ZeroXInfinityClient

client = ZeroXInfinityClient(
    api_key="your_api_key",
    secret_key_bytes=secret_key  # Ed25519 私钥
)

# 创建订单
order = client.create_order(
    symbol="BTC_USDT",
    side="BUY",
    price="85000.00",
    qty="0.001"
)

4.2 TypeScript SDK

import { ZeroXInfinityClient } from './zero_x_infinity_sdk';

const client = new ZeroXInfinityClient(apiKey, secretKey);
const depth = await client.getDepth('BTC_USDT');

5. 验证

5.1 访问 Swagger UI

cargo run --release -- --gateway --port 8080
# 打开: http://localhost:8080/docs

5.2 测试结果

测试类别数量结果
单元测试293✅ 全部通过
公开端点6✅ 全部通过
私有端点9✅ 全部通过
E2E 总计17✅ 全部通过

6. 总结

本章我们为交易引擎添加了 OpenAPI 文档:

成就结果
Swagger UI可通过 /docs 访问
OpenAPI 规范15 个端点已文档化
Python SDK自动生成(含 Ed25519)
TypeScript SDK类型安全的客户端
零破坏性变更所有现有测试通过

下一章:随着鲁棒性(0x0D)和文档化(0x0E)的完成,基础已经稳固。下一个合理的步骤是 0x0F: 充值与提现 —— 连接区块链实现真正的加密货币资金。