flagrant-api 0.0.2

CLI powered feature-flagging
Documentation
use axum::{
    extract::{Path, Query, State},
    Json,
};
use flagrant::models::{environment, feature};
use flagrant_types::{Feature, FeatureRequestPayload};
use serde::Deserialize;
use sqlx::SqlitePool;

use crate::errors::ServiceError;

#[derive(Debug, Deserialize)]
pub struct FeatureQueryParams {
    name: Option<String>,
    prefix: Option<String>,
}

pub async fn create(
    State(pool): State<SqlitePool>,
    Path(environment_id): Path<u16>,
    Json(feat): Json<FeatureRequestPayload>,
) -> Result<Json<Feature>, ServiceError> {
    let env = environment::fetch(&pool, environment_id).await?;
    let feature = feature::create(&pool, &env, feat.name, feat.value, feat.is_enabled).await?;

    Ok(Json(feature))
}

pub async fn fetch(
    State(pool): State<SqlitePool>,
    Path((environment_id, feature_id)): Path<(u16, u16)>,
) -> Result<Json<Feature>, ServiceError> {
    let env = environment::fetch(&pool, environment_id).await?;
    let feature = feature::fetch(&pool, &env, feature_id).await?;

    Ok(Json(feature))
}

pub async fn update(
    State(pool): State<SqlitePool>,
    Path((environment_id, feature_id)): Path<(u16, u16)>,
    Json(feat): Json<FeatureRequestPayload>,
) -> Result<Json<()>, ServiceError> {
    let env = environment::fetch(&pool, environment_id).await?;
    let feature = feature::fetch(&pool, &env, feature_id).await?;
    feature::update(
        &pool,
        &env,
        &feature,
        feat.name,
        feat.value,
        feat.is_enabled,
    )
    .await?;

    Ok(Json(()))
}

pub async fn list(
    State(pool): State<SqlitePool>,
    Query(params): Query<FeatureQueryParams>,
    Path(environment_id): Path<u16>,
) -> Result<Json<Vec<Feature>>, ServiceError> {
    let env = environment::fetch(&pool, environment_id).await?;
    let features = match (params.prefix, params.name) {
        (Some(prefix), _) => feature::fetch_by_prefix(&pool, &env, prefix).await?,
        (_, Some(name)) => vec![feature::fetch_by_name(&pool, &env, name).await?],
        _ => feature::list(&pool, &env).await?
    };

    Ok(Json(features))
}

pub async fn delete(
    State(pool): State<SqlitePool>,
    Path((environment_id, feature_id)): Path<(u16, u16)>,
) -> Result<Json<()>, ServiceError> {
    let env = environment::fetch(&pool, environment_id).await?;
    let feature = feature::fetch(&pool, &env, feature_id).await?;
    feature::delete(
        &pool,
        &env,
        &feature,
    )
    .await?;

    Ok(Json(()))
}