Skip to content

Services Domain

Manages external infrastructure nodes that CoreAPI integrates with — Castis Streamer nodes, Cache (cproxy), and SLB (ELB). Each node type follows the same pattern: a DB registry for storing connection info, a dedicated HTTP client in pkg/ for runtime communication, and a proxy endpoint for direct API access during development.


Architecture

graph LR
    CoreAPI --> StreamerClient["pkg/StreamerClient"]
    CoreAPI --> CproxyClient["pkg/CproxyClient (planned)"]
    CoreAPI --> ELBClient["pkg/ELBClient (planned)"]
    StreamerClient --> Streamer["Castis Streamer Nodes"]
    CproxyClient --> Cproxy["Cache / cproxy Nodes"]
    ELBClient --> ELB["SLB / ELB Nodes"]
    CoreAPI --> PostgreSQL["PostgreSQL (node registry)"]

Node records are stored in Postgres. At runtime, CoreAPI queries the record to get host and ports, maps it to a lightweight client struct (StreamerNode, etc.), and makes the HTTP call. The DB record and the client are kept separate — updating a node's host in the DB automatically takes effect on the next request.


Implementation Status

Streamer (Castis Streamer)

  • Streamer CRUD (/streamers)
  • Ping endpoint — hits /api/ping, updates status and lastPingedAt
  • pkg/StreamerClientCreateStream, DeleteStream, GetStreams, GetTraffic, ProxyRequest
  • Proxy endpoint — forward any Streamer API path verbatim (/streamers/:id/proxy/*)
  • StreamerNode decoupled from DB model — no import cycle

Cache / cproxy

  • Cache node CRUD
  • pkg/CproxyClient
  • Proxy endpoint

SLB / ELB

  • SLB node CRUD
  • pkg/ELBClient
  • Proxy endpoint

Proxy Endpoint

Before dedicated typed functions are built for each node API, the proxy endpoint provides direct passthrough access to any path on the node: GET /streamers/1/proxy/api/version GET /streamers/1/proxy/api/traffic GET /streamers/1/proxy/api/config GET /streamers/1/proxy/api/v2/files PUT /streamers/1/proxy/api/config

The method, path, query string, and body are all forwarded verbatim. The raw response status and body are passed straight back — no envelope wrapping. When a dedicated handler is built for a path, add it as a named route above the wildcard and the proxy continues to cover everything else.


Node Registration Flow

sequenceDiagram
    participant Dev
    participant CoreAPI
    participant PostgreSQL

    Dev->>CoreAPI: POST /streamers { name, host, httpPort, apiPort }
    CoreAPI->>PostgreSQL: INSERT streamer record
    CoreAPI-->>Dev: 201 { id, status: unknown }
    Dev->>CoreAPI: POST /streamers/:id/ping
    CoreAPI->>Streamer: GET http://host:apiPort/api/ping
    Streamer-->>CoreAPI: 200
    CoreAPI->>PostgreSQL: UPDATE status=online, lastPingedAt=now
    CoreAPI-->>Dev: 200 { status: online, pingedAt }

Changelog

Date Author Change
2026-06-01 Shida Decoupled StreamerNode from service.Streamer — resolved import cycle
2026-06-01 Shida Added ProxyRequest to StreamerClient, ProxyStreamerRequest handler
2026-05-28 Shida Migrated to pkg/response envelope
2026-05-21 Peach Added ping endpoint with 5s timeout
2026-05-19 Peach Initial streamer CRUD