Skip to main content

Routes Structure

The Heimdall API is organized into a clean, hierarchical route structure with versioned endpoints.

Route Hierarchy

/                                   [Root - redirects to /v1]
/health [Health check - root level]

/v1 [API v1 info endpoint]
/v1/health [Health check - also available under v1]
/v1/auth/signin [POST - Sign in with API token]
/v1/auth/validate [POST - Validate API token]

/v1/gps [GET - List GPS data (paginated, authenticated)]
/v1/gps [POST - Create GPS data (admin only, rate-limited)]
/v1/gps/current [GET - Get current GPS (authenticated)]
/v1/gps/{id} [GET - Get GPS by ID (authenticated)]

/v1/settings [GET - Get all settings (admin only)]
/v1/settings/public [GET - Get public settings (no auth)]
/v1/settings/{key} [GET - Get setting by key (admin only)]
/v1/settings [POST - Create setting (admin only)]
/v1/settings/{key} [PUT - Update setting (admin only)]
/v1/settings/{key} [DELETE - Delete setting (admin only)]

/v1/stats/public [GET - Get public stats (no auth)]

/v1/ws [WS - WebSocket connection]

/v1/gql [POST/GET - GraphQL endpoint (authenticated)]
/v1/graphiql [GET - GraphiQL IDE (dev only, no auth)]
/v1/schema [GET - GraphQL schema SDL (no auth)]

/v1/api-keys [GET - List API keys (admin only)]
/v1/api-keys [POST - Create API key (admin only)]
/v1/api-keys/{id} [GET - Get API key by ID (admin only)]
/v1/api-keys/{id} [DELETE - Delete API key (admin only)]

/v1/roles [GET - List roles (admin only)]
/v1/roles [POST - Create role (admin only)]
/v1/roles/{id} [GET - Get role by ID (admin only)]
/v1/roles/{id} [PUT - Update role (admin only)]
/v1/roles/{id} [DELETE - Delete role (admin only)]

/v1/permissions [GET - List permissions (admin only)]
/v1/permissions [POST - Create permission (admin only)]
/v1/permissions/{id} [GET - Get permission by ID (admin only)]
/v1/permissions/{id} [PUT - Update permission (admin only)]
/v1/permissions/{id} [DELETE - Delete permission (admin only)]

/v1/users [GET - List users (admin only)]
/v1/users [POST - Create user (admin only)]
/v1/users/{id} [GET - Get user by ID (admin only)]
/v1/users/{id} [PUT - Update user (admin only)]
/v1/users/{id} [DELETE - Delete user (admin only)]

/v1/swagger-ui [GET - Redirect to /v1/swagger-ui/]
/v1/swagger-ui/ [GET - Swagger UI]
/v1/api-docs/openapi.json [GET - OpenAPI JSON specification]

Route Configuration Flow

main.rs

App::new()
.configure(routes::root_routes) // "/" and "/health"
.configure(routes::configure_public_routes) // Public routes under /v1
.service(
web::scope("/v1")
.configure(routes::configure_routes) // All authenticated v1 API routes
.configure(routes::configure_graphql) // GraphQL routes
)
// Swagger UI routes configured directly in main.rs

routes/mod.rs

Public Functions (called from main.rs):

  • root_routes() - Root endpoint (redirects to /v1)
  • configure_public_routes() - Public routes including /health, /v1, /v1/health
  • configure_routes() - All authenticated v1 API routes
  • configure_graphql() - GraphQL endpoints (/gql, /graphiql, /schema)

Route Modules (configured by configure_routes):

  • auth::configure - Authentication endpoints
  • api_keys::configure - API key management
  • roles::configure - Role management
  • permissions::configure - Permission management
  • users::configure - User management
  • gps::configure - GPS data endpoints
  • settings::configure - Settings management
  • stats::configure - Statistics endpoints
  • websocket::configure - WebSocket endpoint

Authentication & Authorization

No Authentication Required

  • GET / - Root redirect to /v1
  • GET /health - Health check
  • GET /v1 - API info
  • GET /v1/health - Health check
  • GET /v1/settings/public - Public settings
  • GET /v1/stats/public - Public statistics
  • POST /v1/auth/signin - Sign in
  • POST /v1/auth/validate - Validate token
  • GET /v1/graphiql - GraphiQL IDE (development only)
  • GET /v1/schema - GraphQL schema

Authentication Required (Any Authenticated User)

  • GET /v1/gps - List GPS data
  • GET /v1/gps/current - Current GPS
  • GET /v1/gps/{id} - GPS by ID
  • POST /v1/gql - GraphQL endpoint
  • GET /v1/gql - GraphQL endpoint

Admin Only

  • POST /v1/gps - Create GPS (rate-limited: 30 req/60s)
  • GET /v1/settings - All settings
  • GET /v1/settings/{key} - Setting by key
  • POST /v1/settings - Create setting
  • PUT /v1/settings/{key} - Update setting
  • DELETE /v1/settings/{key} - Delete setting
  • GET /v1/api-keys - List API keys
  • POST /v1/api-keys - Create API key
  • GET /v1/api-keys/{id} - Get API key
  • DELETE /v1/api-keys/{id} - Delete API key
  • GET /v1/roles - List roles
  • POST /v1/roles - Create role
  • GET /v1/roles/{id} - Get role
  • PUT /v1/roles/{id} - Update role
  • DELETE /v1/roles/{id} - Delete role
  • GET /v1/permissions - List permissions
  • POST /v1/permissions - Create permission
  • GET /v1/permissions/{id} - Get permission
  • PUT /v1/permissions/{id} - Update permission
  • DELETE /v1/permissions/{id} - Delete permission
  • GET /v1/users - List users
  • POST /v1/users - Create user
  • GET /v1/users/{id} - Get user
  • PUT /v1/users/{id} - Update user
  • DELETE /v1/users/{id} - Delete user

All responses include _links with self-referencing URLs:

Single Resource:

{
"data": { ... },
"_links": {
"self": "https://api.example.com/v1/gps/abc-123"
}
}

Paginated Resource:

{
"data": [...],
"pagination": { ... },
"_links": {
"self": "https://api.example.com/v1/gps?page=2&limit=10",
"first": "https://api.example.com/v1/gps?page=1&limit=10",
"prev": "https://api.example.com/v1/gps?page=1&limit=10",
"next": "https://api.example.com/v1/gps?page=3&limit=10",
"last": "https://api.example.com/v1/gps?page=10&limit=10"
}
}

Middleware Stack

  1. CORS - Environment-aware (permissive in dev, strict in prod)
  2. Logger - HTTP request logging
  3. TracingLogger - Structured logging with tracing
  4. AuthMiddleware - Bearer token authentication (per-route)
  5. RequireRole - Role-based access control (per-route)
  6. RateLimitMiddleware - Rate limiting (per-route)

Benefits of This Structure

Clear Separation: Root-level vs versioned API routes
Scalable: Easy to add /v2 scope in the future
Flexible Auth: Per-route authentication and authorization
DRY: Reusable route configuration functions
Type-Safe: Compile-time route verification
HATEOAS: Self-documenting API with links