obzenflow_core 0.2.4

Core domain layer for ObzenFlow - pure abstractions with minimal dependencies
Documentation
// SPDX-License-Identifier: MIT OR Apache-2.0
// SPDX-FileCopyrightText: 2025-2026 ObzenFlow Contributors
// https://obzenflow.dev

//! HTTP endpoint abstraction

use super::error::EndpointError;
use super::managed::ManagedResponse;
use super::surface::{RouteKind, RoutePolicy, SurfacePolicy};
use super::types::{HttpMethod, Request};
use async_trait::async_trait;

/// Managed-route metadata exposed by `WebSurface`-backed endpoints.
///
/// This is an optional, framework-neutral signal that the infrastructure layer can
/// use for policy enforcement and observability decisions without depending on
/// any concrete web framework types.
#[derive(Debug, Clone)]
pub struct ManagedRouteInfo {
    pub kind: RouteKind,
    pub surface_policy: Option<SurfacePolicy>,
    pub route_policy: RoutePolicy,
}

/// Trait for HTTP endpoints that can be registered with a web server
///
/// This trait is implemented by any component that wants to expose HTTP endpoints.
/// The implementation is framework-agnostic.
#[async_trait]
pub trait HttpEndpoint: Send + Sync {
    /// The path pattern this endpoint handles
    ///
    /// Examples:
    /// - "/metrics" for exact path
    /// - "/api/v1/users" for exact path
    /// - Could support patterns in the future like "/api/v1/users/:id"
    fn path(&self) -> &str;

    /// HTTP methods this endpoint supports
    ///
    /// Return an empty slice to support all methods
    fn methods(&self) -> &[HttpMethod];

    /// Handle an incoming HTTP request
    ///
    /// This method is called when a request matches this endpoint's path and method.
    /// The implementation should process the request and return an appropriate response.
    async fn handle(&self, request: Request) -> Result<ManagedResponse, EndpointError>;

    /// Optional method to get endpoint metadata
    ///
    /// This can be used for documentation, monitoring, etc.
    /// Default implementation returns None.
    fn metadata(&self) -> Option<EndpointMetadata> {
        None
    }

    /// Optional managed-route metadata for endpoints that are derived from `WebSurface`.
    fn managed_route(&self) -> Option<ManagedRouteInfo> {
        None
    }
}

/// Metadata about an endpoint
#[derive(Debug, Clone)]
pub struct EndpointMetadata {
    /// Human-readable name for the endpoint
    pub name: String,

    /// Description of what the endpoint does
    pub description: Option<String>,

    /// Version of the endpoint API
    pub version: Option<String>,

    /// Tags for categorization
    pub tags: Vec<String>,
}

impl EndpointMetadata {
    /// Create new endpoint metadata
    pub fn new(name: String) -> Self {
        Self {
            name,
            description: None,
            version: None,
            tags: Vec::new(),
        }
    }

    /// Add a description
    pub fn with_description(mut self, description: String) -> Self {
        self.description = Some(description);
        self
    }

    /// Add a version
    pub fn with_version(mut self, version: String) -> Self {
        self.version = Some(version);
        self
    }

    /// Add tags
    pub fn with_tags(mut self, tags: Vec<String>) -> Self {
        self.tags = tags;
        self
    }
}