Skip to content
//! Request and response bodies for the HTTP API.

use serde::{Deserialize, Serialize};

use crate::app::{AppSummary, Host, ImageRef, ImageSource, ImageVersion};
use crate::job::JobView;

/// Declarative application infrastructure accepted by
/// `POST /api/v1/infrastructure/apply`.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct InfrastructureSpec {
    /// Public hostname that identifies the application.
    pub host: Host,
    /// OCI repository without a tag or digest.
    pub source: ImageSource,
    /// OCI tag to deploy from that repository.
    pub version: ImageVersion,
}

/// Body of `POST /api/v1/apps/{host}/update`.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct UpdateImageRequest {
    /// Image to roll the application onto.
    pub image: ImageRef,
    /// Explicit `--auto-update` value. Omit to leave the flag off entirely.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub auto_update: Option<bool>,
}

/// Body of `GET /api/v1/apps`.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AppsResponse {
    /// Applications currently known to the Docker daemon.
    pub apps: Vec<AppSummary>,
}

/// Body of `GET /api/v1/jobs`.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct JobsResponse {
    /// Jobs retained by the server, newest first.
    pub jobs: Vec<JobView>,
}

/// Body of `GET /api/v1/health`, the one unauthenticated route.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HealthResponse {
    /// Always `twice`.
    pub service: String,
    /// Server crate version.
    pub version: String,
}

/// Error body returned for every non-2xx response.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ApiErrorBody {
    /// Stable machine-readable code, e.g. `unauthorized`, `unknown_app`.
    pub error: String,
    /// Operator-facing detail.
    pub message: String,
}