Files
NxMesh-old/docs/api.md
GW_MC 43b2e44d95 Add project structure and roadmap documentation
- Created `project-structure.md` to outline the directory layout, crate dependencies, design principles, module guidelines, and naming conventions for the NxMesh codebase.
- Introduced `roadmap.md` detailing the development phases, milestones, tasks, deliverables, and resource requirements for the NxMesh project, spanning from foundational setup to enterprise features.
2026-03-03 04:13:31 +00:00

20 KiB

NxMesh API Specification

Overview

This document outlines the API structure for NxMesh. The system exposes:

  • REST API for external integrations and Web UI
  • gRPC API for master-agent communication
  • WebSocket API for real-time events

REST API

Base Information

Property Value
Base URL https://api.nxmesh.io/v1
Content-Type application/json
Authentication Bearer Token (JWT)
Rate Limit 1000 requests/minute

Authentication

Login

POST /auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "secure_password"
}

Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Refresh Token

POST /auth/refresh
Content-Type: application/json

{
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}

Organizations

List Organizations

GET /organizations?page=1&per_page=20
Authorization: Bearer {token}

Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Acme Corp",
      "slug": "acme-corp",
      "created_at": "2026-01-15T10:30:00Z",
      "updated_at": "2026-01-15T10:30:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 1
  }
}

Create Organization

POST /organizations
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "Acme Corp",
  "slug": "acme-corp"
}

Get Organization

GET /organizations/{organization_id}
Authorization: Bearer {token}

Update Organization

PATCH /organizations/{organization_id}
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "Acme Corporation"
}

Delete Organization

DELETE /organizations/{organization_id}
Authorization: Bearer {token}

Workspaces

List Workspaces

GET /organizations/{organization_id}/workspaces?page=1&per_page=20
Authorization: Bearer {token}

Response:

{
  "data": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "organization_id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Production",
      "slug": "production",
      "created_at": "2026-01-15T10:30:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 3
  }
}

Create Workspace

POST /organizations/{organization_id}/workspaces
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "Staging",
  "slug": "staging"
}

Get Workspace

GET /workspaces/{workspace_id}
Authorization: Bearer {token}

Update Workspace

PATCH /workspaces/{workspace_id}
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "Staging Environment"
}

Delete Workspace

DELETE /workspaces/{workspace_id}
Authorization: Bearer {token}

Agents

List Agents

GET /workspaces/{workspace_id}/agents?page=1&per_page=20&state=online
Authorization: Bearer {token}

Query Parameters:

  • state - Filter by state: online, offline, degraded, all
  • label_selector - Filter by labels: env=production,region=us-east

Response:

{
  "data": [
    {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "workspace_id": "660e8400-e29b-41d4-a716-446655440001",
      "name": "web-server-01",
      "hostname": "web-01.internal",
      "ip_address": "10.0.1.10",
      "version": "0.1.0",
      "state": "online",
      "deployment_mode": "docker_sidecar",
      "last_seen_at": "2026-03-02T12:00:00Z",
      "capabilities": ["http2", "websocket"],
      "labels": {
        "env": "production",
        "region": "us-east-1"
      },
      "created_at": "2026-02-01T10:00:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 5
  }
}

Get Agent

GET /agents/{agent_id}
Authorization: Bearer {token}

Response includes health details:

{
  "id": "770e8400-e29b-41d4-a716-446655440002",
  "workspace_id": "660e8400-e29b-41d4-a716-446655440001",
  "name": "web-server-01",
  "hostname": "web-01.internal",
  "ip_address": "10.0.1.10",
  "version": "0.1.0",
  "state": "online",
  "deployment_mode": "docker_sidecar",
  "last_seen_at": "2026-03-02T12:00:00Z",
  "capabilities": ["http2", "websocket"],
  "labels": {
    "env": "production",
    "region": "us-east-1"
  },
  "health": {
    "nginx_status": "running",
    "nginx_uptime_seconds": 86400,
    "active_connections": 42,
    "requests_per_second": 150.5,
    "cpu_percent": 25.0,
    "memory_used_mb": 512,
    "config_version": 42
  },
  "created_at": "2026-02-01T10:00:00Z"
}

Create Agent Registration Token

POST /workspaces/{workspace_id}/agents/tokens
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "web-server-02",
  "labels": {
    "env": "production",
    "region": "us-west-1"
  },
  "expires_in_hours": 24
}

Response:

{
  "token": "nxmesh_agent_eyJhZ2VudF9pZCI6ICI3NzBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDMi...",
  "agent_id": "770e8400-e29b-41d4-a716-446655440003",
  "expires_at": "2026-03-03T12:00:00Z"
}

Update Agent

PATCH /agents/{agent_id}
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "web-server-01-renamed",
  "labels": {
    "env": "production",
    "region": "us-east-1",
    "tier": "web"
  }
}

Delete Agent

DELETE /agents/{agent_id}
Authorization: Bearer {token}

Reload Agent Nginx

POST /agents/{agent_id}/reload
Authorization: Bearer {token}

Response:

{
  "success": true,
  "message": "Nginx reloaded successfully",
  "timestamp": "2026-03-02T12:05:00Z"
}

Virtual Hosts

List Virtual Hosts

GET /workspaces/{workspace_id}/virtual-hosts?page=1&per_page=20
Authorization: Bearer {token}

Response:

{
  "data": [
    {
      "id": "880e8400-e29b-41d4-a716-446655440004",
      "workspace_id": "660e8400-e29b-41d4-a716-446655440001",
      "name": "Main Website",
      "server_name": "example.com www.example.com",
      "listen_port": 443,
      "ssl_enabled": true,
      "ssl_certificate_id": "990e8400-e29b-41d4-a716-446655440005",
      "http2_enabled": true,
      "target_agents": {
        "type": "all"
      },
      "created_at": "2026-02-01T10:00:00Z",
      "updated_at": "2026-02-15T14:30:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 10
  }
}

Create Virtual Host

POST /workspaces/{workspace_id}/virtual-hosts
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "API Gateway",
  "server_name": "api.example.com",
  "listen_port": 443,
  "ssl_enabled": true,
  "ssl_certificate_id": "990e8400-e29b-41d4-a716-446655440005",
  "http2_enabled": true,
  "locations": [
    {
      "path": "/api/v1",
      "upstream_id": "aa0e8400-e29b-41d4-a716-446655440006",
      "custom_headers": [
        {
          "name": "X-Forwarded-Proto",
          "value": "$scheme"
        }
      ]
    },
    {
      "path": "/health",
      "proxy_pass": "http://localhost:8080/health"
    }
  ],
  "target_agents": {
    "type": "selector",
    "label_selector": "env=production"
  }
}

Get Virtual Host

GET /virtual-hosts/{virtual_host_id}
Authorization: Bearer {token}

Update Virtual Host

PATCH /virtual-hosts/{virtual_host_id}
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "API Gateway v2",
  "locations": [
    {
      "path": "/api/v2",
      "upstream_id": "aa0e8400-e29b-41d4-a716-446655440007"
    }
  ]
}

Delete Virtual Host

DELETE /virtual-hosts/{virtual_host_id}
Authorization: Bearer {token}

Upstreams

List Upstreams

GET /workspaces/{workspace_id}/upstreams?page=1&per_page=20
Authorization: Bearer {token}

Response:

{
  "data": [
    {
      "id": "aa0e8400-e29b-41d4-a716-446655440006",
      "workspace_id": "660e8400-e29b-41d4-a716-446655440001",
      "name": "api-backend",
      "algorithm": "round_robin",
      "servers": [
        {
          "address": "10.0.1.20:8080",
          "weight": 1,
          "backup": false,
          "max_fails": 3,
          "fail_timeout": 30
        },
        {
          "address": "10.0.1.21:8080",
          "weight": 1,
          "backup": false,
          "max_fails": 3,
          "fail_timeout": 30
        }
      ],
      "health_check": {
        "enabled": true,
        "path": "/health",
        "interval": 10,
        "timeout": 5
      },
      "created_at": "2026-02-01T10:00:00Z",
      "updated_at": "2026-02-15T14:30:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 5
  }
}

Create Upstream

POST /workspaces/{workspace_id}/upstreams
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "web-backend",
  "algorithm": "least_connections",
  "servers": [
    {
      "address": "10.0.1.30:8080",
      "weight": 2,
      "backup": false
    },
    {
      "address": "10.0.1.31:8080",
      "weight": 1,
      "backup": false
    },
    {
      "address": "10.0.1.32:8080",
      "weight": 1,
      "backup": true
    }
  ],
  "health_check": {
    "enabled": true,
    "path": "/health",
    "interval": 10,
    "timeout": 5
  }
}

Get Upstream

GET /upstreams/{upstream_id}
Authorization: Bearer {token}

Update Upstream

PATCH /upstreams/{upstream_id}
Authorization: Bearer {token}
Content-Type: application/json

{
  "servers": [
    {
      "address": "10.0.1.30:8080",
      "weight": 3,
      "backup": false
    }
  ]
}

Delete Upstream

DELETE /upstreams/{upstream_id}
Authorization: Bearer {token}

Certificates

List Certificates

GET /workspaces/{workspace_id}/certificates?page=1&per_page=20
Authorization: Bearer {token}

Response:

{
  "data": [
    {
      "id": "990e8400-e29b-41d4-a716-446655440005",
      "workspace_id": "660e8400-e29b-41d4-a716-446655440001",
      "domain": "example.com",
      "is_wildcard": false,
      "provider": "letsencrypt",
      "status": "active",
      "issued_at": "2026-02-01T10:00:00Z",
      "expires_at": "2026-05-01T10:00:00Z",
      "auto_renew": true,
      "created_at": "2026-02-01T10:00:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 3
  }
}

Request Certificate

POST /workspaces/{workspace_id}/certificates
Authorization: Bearer {token}
Content-Type: application/json

{
  "domain": "api.example.com",
  "provider": "letsencrypt",
  "auto_renew": true
}

Get Certificate

GET /certificates/{certificate_id}
Authorization: Bearer {token}

Delete Certificate

DELETE /certificates/{certificate_id}
Authorization: Bearer {token}

Metrics

Get Workspace Metrics

GET /workspaces/{workspace_id}/metrics?from=2026-03-01T00:00:00Z&to=2026-03-02T00:00:00Z
Authorization: Bearer {token}

Response:

{
  "requests_total": 1234567,
  "requests_per_second": 150.5,
  "error_rate": 0.001,
  "active_connections": 42,
  "bandwidth": {
    "in_bytes": 1073741824,
    "out_bytes": 5368709120
  },
  "status_codes": {
    "2xx": 1230000,
    "3xx": 4000,
    "4xx": 500,
    "5xx": 67
  }
}

Get Agent Metrics

GET /agents/{agent_id}/metrics?from=2026-03-01T00:00:00Z&to=2026-03-02T00:00:00Z
Authorization: Bearer {token}

Access Logs

Query Access Logs

GET /workspaces/{workspace_id}/access-logs?from=2026-03-01T00:00:00Z&to=2026-03-02T00:00:00Z&status_code=500&limit=100
Authorization: Bearer {token}

Response:

{
  "data": [
    {
      "id": "bb0e8400-e29b-41d4-a716-446655440008",
      "agent_id": "770e8400-e29b-41d4-a716-446655440002",
      "timestamp": "2026-03-02T10:30:00Z",
      "remote_addr": "192.168.1.100",
      "method": "GET",
      "uri": "/api/error",
      "protocol": "HTTP/1.1",
      "host": "api.example.com",
      "status": 500,
      "body_bytes_sent": 123,
      "response_time_ms": 150.5,
      "user_agent": "Mozilla/5.0...",
      "referer": "https://example.com/",
      "request_id": "req-123-456"
    }
  ],
  "meta": {
    "total": 67,
    "limit": 100
  }
}

Error Responses

All errors follow this format:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "request_id": "req-abc-123",
    "details": [
      {
        "field": "server_name",
        "message": "Invalid domain format",
        "code": "INVALID_FORMAT"
      }
    ]
  }
}

Error Codes

Code HTTP Status Description
UNAUTHORIZED 401 Authentication required or invalid credentials
FORBIDDEN 403 Insufficient permissions
NOT_FOUND 404 Resource not found
VALIDATION_ERROR 422 Request validation failed
CONFLICT 409 Resource conflict (e.g., duplicate slug)
RATE_LIMITED 429 Too many requests
INTERNAL_ERROR 500 Server internal error
SERVICE_UNAVAILABLE 503 Service temporarily unavailable

gRPC API (Master-Agent)

Service Definition

syntax = "proto3";
package nxmesh.agent.v1;

option go_package = "github.com/nxmesh/api/agent/v1";

// AgentService defines the bidirectional communication between master and agents
service AgentService {
  // Stream establishes a persistent connection for real-time communication
  rpc Stream(stream AgentMessage) returns (stream MasterMessage);
  
  // ReportHealth sends a health report to the master
  rpc ReportHealth(HealthReport) returns (Ack);
  
  // ReportMetrics sends metrics batch to the master
  rpc ReportMetrics(MetricsBatch) returns (Ack);
}

// Messages sent from agent to master
message AgentMessage {
  string agent_id = 1;
  int64 timestamp = 2;
  oneof payload {
    RegistrationRequest registration = 3;
    HealthReport health = 4;
    ConfigStatus config_status = 5;
    MetricsBatch metrics = 6;
    LogBatch logs = 7;
    Event event = 8;
  }
}

// Messages sent from master to agent
message MasterMessage {
  int64 timestamp = 1;
  oneof payload {
    RegistrationResponse registration_response = 2;
    ConfigUpdate config_update = 3;
    Command command = 4;
    Ack ack = 5;
    Error error = 6;
  }
}

// Registration
message RegistrationRequest {
  string token = 1;
  string hostname = 2;
  string ip_address = 3;
  string version = 4;
  repeated string capabilities = 5;
  map<string, string> labels = 6;
  DeploymentMode deployment_mode = 7;
}

message RegistrationResponse {
  string agent_id = 1;
  bool success = 2;
  string error_message = 3;
  int64 heartbeat_interval_seconds = 4;
}

enum DeploymentMode {
  DEPLOYMENT_MODE_UNSPECIFIED = 0;
  DOCKER_SIDECAR = 1;
  KUBERNETES_SIDECAR = 2;
  STANDALONE = 3;
}

// Health Reporting
message HealthReport {
  NginxStatus nginx = 1;
  SystemMetrics system = 2;
  string config_checksum = 3;
  int64 config_version = 4;
  repeated Alert alerts = 5;
}

message NginxStatus {
  bool is_running = 1;
  uint32 pid = 2;
  uint64 uptime_seconds = 3;
  uint32 active_connections = 4;
  uint64 total_requests = 5;
  float requests_per_second = 6;
}

message SystemMetrics {
  float cpu_percent = 1;
  uint64 memory_used_bytes = 2;
  uint64 memory_total_bytes = 3;
  uint64 disk_used_bytes = 4;
  uint64 disk_total_bytes = 5;
  float load_average_1m = 6;
}

message Alert {
  string id = 1;
  string severity = 2;  // info, warning, error, critical
  string message = 3;
  int64 timestamp = 4;
}

// Configuration
message ConfigUpdate {
  string config_id = 1;
  int64 version = 2;
  repeated VirtualHost virtual_hosts = 3;
  repeated Upstream upstreams = 4;
  map<string, Certificate> certificates = 5;
  GlobalSettings global_settings = 6;
}

message VirtualHost {
  string id = 1;
  string name = 2;
  string server_name = 3;
  uint32 listen_port = 4;
  bool ssl_enabled = 5;
  string ssl_certificate_id = 6;
  bool http2_enabled = 7;
  bool http3_enabled = 8;
  repeated Location locations = 9;
  map<string, string> custom_directives = 10;
}

message Location {
  string path = 1;
  string proxy_pass = 2;
  string upstream_id = 3;
  string root = 4;
  string index = 5;
  repeated Header custom_headers = 6;
  repeated RewriteRule rewrite_rules = 7;
  map<string, string> custom_directives = 8;
}

message Header {
  string name = 1;
  string value = 2;
  bool always = 3;
}

message RewriteRule {
  string pattern = 1;
  string replacement = 2;
  string flag = 3;
}

message Upstream {
  string id = 1;
  string name = 2;
  LoadBalanceAlgorithm algorithm = 3;
  repeated UpstreamServer servers = 4;
  HealthCheckConfig health_check = 5;
  uint32 keepalive_connections = 6;
}

enum LoadBalanceAlgorithm {
  LOAD_BALANCE_ALGORITHM_UNSPECIFIED = 0;
  ROUND_ROBIN = 1;
  LEAST_CONNECTIONS = 2;
  IP_HASH = 3;
  WEIGHTED_ROUND_ROBIN = 4;
}

message UpstreamServer {
  string address = 1;
  uint32 weight = 2;
  bool backup = 3;
  bool down = 4;
  uint32 max_fails = 5;
  uint32 fail_timeout_seconds = 6;
}

message HealthCheckConfig {
  bool enabled = 1;
  string path = 2;
  uint32 interval_seconds = 3;
  uint32 timeout_seconds = 4;
  uint32 healthy_threshold = 5;
  uint32 unhealthy_threshold = 6;
}

message Certificate {
  string id = 1;
  string domain = 2;
  string certificate_pem = 3;
  string private_key_pem = 4;
  int64 expires_at = 5;
}

message GlobalSettings {
  map<string, string> nginx_directives = 1;
  map<string, string> env_vars = 2;
}

message ConfigStatus {
  string config_id = 1;
  int64 version = 2;
  ConfigApplyStatus status = 3;
  string error_message = 4;
  int64 applied_at = 5;
}

enum ConfigApplyStatus {
  CONFIG_APPLY_STATUS_UNSPECIFIED = 0;
  PENDING = 1;
  VALIDATING = 2;
  APPLYING = 3;
  SUCCESS = 4;
  FAILED = 5;
  ROLLED_BACK = 6;
}

// Metrics
message MetricsBatch {
  int64 timestamp = 1;
  repeated Metric metrics = 2;
}

message Metric {
  string name = 1;
  double value = 2;
  int64 timestamp = 3;
  map<string, string> labels = 4;
  MetricType type = 5;
}

enum MetricType {
  METRIC_TYPE_UNSPECIFIED = 0;
  GAUGE = 1;
  COUNTER = 2;
  HISTOGRAM = 3;
}

// Logs
message LogBatch {
  repeated LogEntry entries = 1;
}

message LogEntry {
  int64 timestamp = 1;
  string level = 2;
  string message = 3;
  map<string, string> fields = 4;
}

// Commands
message Command {
  string command_id = 1;
  oneof command {
    ReloadCommand reload = 2;
    RestartCommand restart = 3;
    StopCommand stop = 4;
    GetStatusCommand get_status = 5;
    ValidateConfigCommand validate_config = 6;
  }
}

message ReloadCommand {
  bool graceful = 1;
}

message RestartCommand {
  bool force = 1;
}

message StopCommand {
  bool graceful = 1;
  uint32 timeout_seconds = 2;
}

message GetStatusCommand {}

message ValidateConfigCommand {
  string config_content = 1;
}

// Events
message Event {
  string event_id = 1;
  string event_type = 2;
  int64 timestamp = 3;
  map<string, string> data = 4;
}

// Common messages
message Ack {
  string message_id = 1;
  bool success = 2;
  string error_message = 3;
}

message Error {
  string code = 1;
  string message = 2;
  map<string, string> details = 3;
}

WebSocket API

Connection

Connect to WebSocket endpoint with JWT token:

const ws = new WebSocket('wss://api.nxmesh.io/v1/events?token={jwt_token}');

Event Types

Agent Connected

{
  "type": "agent.connected",
  "timestamp": "2026-03-02T12:00:00Z",
  "data": {
    "agent_id": "770e8400-e29b-41d4-a716-446655440002",
    "hostname": "web-01.internal",
    "ip_address": "10.0.1.10"
  }
}

Agent Disconnected

{
  "type": "agent.disconnected",
  "timestamp": "2026-03-02T12:05:00Z",
  "data": {
    "agent_id": "770e8400-e29b-41d4-a716-446655440002",
    "reason": "connection_timeout"
  }
}

Config Applied

{
  "type": "config.applied",
  "timestamp": "2026-03-02T12:10:00Z",
  "data": {
    "agent_id": "770e8400-e29b-41d4-a716-446655440002",
    "config_id": "config-123",
    "version": 42,
    "duration_ms": 150,
    "success": true
  }
}

Health Alert

{
  "type": "health.alert",
  "timestamp": "2026-03-02T12:15:00Z",
  "data": {
    "agent_id": "770e8400-e29b-41d4-a716-446655440002",
    "alert_id": "alert-456",
    "severity": "warning",
    "message": "High CPU usage: 85%",
    "metric": "cpu_percent",
    "value": 85.0
  }
}

Subscribing to Events

Clients can subscribe to specific event types:

{
  "action": "subscribe",
  "events": ["agent.*", "config.*"],
  "filter": {
    "workspace_id": "660e8400-e29b-41d4-a716-446655440001"
  }
}