Skip to content

Latest commit

 

History

History
520 lines (398 loc) · 13.7 KB

File metadata and controls

520 lines (398 loc) · 13.7 KB

0x0E OpenAPI Integration

🇺🇸 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

Term Definition
OpenAPI Industry-standard API specification format (formerly Swagger)
utoipa Rust crate for compile-time OpenAPI generation
Swagger UI Interactive API documentation interface
Code-First Generate 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:

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)

Endpoint Method Description
/api/v1/health GET Health check
/api/v1/public/depth GET Order book depth
/api/v1/public/klines GET K-line data
/api/v1/public/assets GET Asset list
/api/v1/public/symbols GET Trading pairs
/api/v1/public/exchange_info GET Exchange metadata

3.2 Private Endpoints (Ed25519 Auth)

Endpoint Method Description
/api/v1/private/order POST Create order
/api/v1/private/cancel POST Cancel order
/api/v1/private/orders GET Query orders
/api/v1/private/trades GET Trade history
/api/v1/private/balances GET Balance query
/api/v1/private/balances/all GET All balances
/api/v1/private/transfer POST Internal transfer
/api/v1/private/transfer/{id} GET Transfer 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 Category Tests Result
Unit Tests 293 ✅ All pass
Public Endpoints 6 ✅ All pass
Private Endpoints 9 ✅ All pass
E2E Total 17 ✅ All pass

6. Summary

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

Achievement Result
Swagger UI Available at /docs
OpenAPI Spec 15 endpoints documented
Python SDK Auto-generated with Ed25519
TypeScript SDK Type-safe client
Zero Breaking Changes All 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)
utoipa Rust 编译时 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

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/health GET 健康检查
/api/v1/public/depth GET 订单簿深度
/api/v1/public/klines GET K 线数据
/api/v1/public/assets GET 资产列表
/api/v1/public/symbols GET 交易对
/api/v1/public/exchange_info GET 交易所信息

3.2 私有端点(Ed25519 认证)

端点 方法 描述
/api/v1/private/order POST 创建订单
/api/v1/private/cancel POST 取消订单
/api/v1/private/orders GET 查询订单
/api/v1/private/trades GET 成交历史
/api/v1/private/balances GET 余额查询
/api/v1/private/balances/all GET 所有余额
/api/v1/private/transfer POST 内部划转
/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: 充值与提现 —— 连接区块链实现真正的加密货币资金。