Files
NxMesh/apps/nxmesh-master/src/routes/api/proxy/rewrite_rules.rs
2026-07-18 04:54:29 +00:00

149 lines
4.1 KiB
Rust

use std::sync::Arc;
use axum::{
Json,
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::routes::api::{ApiRouter, AppError};
use crate::service::proxy::rewrite_rule::{
CreateRewriteRuleParams, RewriteRuleService, UpdateRewriteRuleParams,
};
use crate::service::proxy::types::RewriteRuleConfig;
#[derive(Serialize)]
pub(crate) struct RewriteRuleResponse {
pub id: Uuid,
pub location_id: Uuid,
pub pattern: String,
pub replacement: String,
pub flag: Option<String>,
pub priority: i32,
pub override_of_id: Option<Uuid>,
}
impl From<RewriteRuleConfig> for RewriteRuleResponse {
fn from(c: RewriteRuleConfig) -> Self {
Self {
id: c.id,
location_id: c.location_id,
pattern: c.pattern,
replacement: c.replacement,
flag: c.flag,
priority: c.priority,
override_of_id: c.override_of_id,
}
}
}
#[derive(Deserialize)]
pub(crate) struct CreateRewriteRuleRequest {
pub pattern: String,
pub replacement: String,
pub flag: Option<String>,
pub priority: i32,
pub override_of_id: Option<Uuid>,
}
impl From<CreateRewriteRuleRequest> for CreateRewriteRuleParams {
fn from(r: CreateRewriteRuleRequest) -> Self {
Self {
location_id: Uuid::nil(),
pattern: r.pattern,
replacement: r.replacement,
flag: r.flag,
priority: r.priority,
override_of_id: r.override_of_id,
}
}
}
#[derive(Deserialize)]
pub(crate) struct UpdateRewriteRuleRequest {
pub location_id: Option<Uuid>,
pub pattern: Option<String>,
pub replacement: Option<String>,
pub flag: Option<Option<String>>,
pub priority: Option<i32>,
pub override_of_id: Option<Option<Uuid>>,
}
impl From<UpdateRewriteRuleRequest> for UpdateRewriteRuleParams {
fn from(r: UpdateRewriteRuleRequest) -> Self {
Self {
location_id: r.location_id,
pattern: r.pattern,
replacement: r.replacement,
flag: r.flag,
priority: r.priority,
override_of_id: r.override_of_id,
}
}
}
async fn list_rewrite_rules(
State(svc): State<Arc<dyn RewriteRuleService>>,
Path(location_id): Path<Uuid>,
) -> Result<Json<Vec<RewriteRuleResponse>>, AppError> {
let rules = svc.list_by_location(location_id).await?;
Ok(Json(rules.into_iter().map(Into::into).collect()))
}
async fn create_rewrite_rule(
State(svc): State<Arc<dyn RewriteRuleService>>,
Path(location_id): Path<Uuid>,
Json(body): Json<CreateRewriteRuleRequest>,
) -> Result<impl IntoResponse, AppError> {
let mut params = CreateRewriteRuleParams::from(body);
params.location_id = location_id;
let rule = svc.create(params).await?;
Ok((StatusCode::CREATED, Json(RewriteRuleResponse::from(rule))))
}
async fn get_rewrite_rule(
State(svc): State<Arc<dyn RewriteRuleService>>,
Path(id): Path<Uuid>,
) -> Result<Json<RewriteRuleResponse>, AppError> {
let rule = svc.get(id).await?;
Ok(Json(rule.into()))
}
async fn update_rewrite_rule(
State(svc): State<Arc<dyn RewriteRuleService>>,
Path(id): Path<Uuid>,
Json(body): Json<UpdateRewriteRuleRequest>,
) -> Result<Json<RewriteRuleResponse>, AppError> {
let rule = svc.update(id, body.into()).await?;
Ok(Json(rule.into()))
}
async fn delete_rewrite_rule(
State(svc): State<Arc<dyn RewriteRuleService>>,
Path(id): Path<Uuid>,
) -> Result<impl IntoResponse, AppError> {
let deleted = svc.delete(id).await?;
if deleted {
Ok((StatusCode::NO_CONTENT,))
} else {
Err(AppError::NotFound)
}
}
pub(super) fn routes() -> ApiRouter {
ApiRouter::new()
.route(
"/locations/{location_id}/rewrite-rules",
axum::routing::get(list_rewrite_rules).post(create_rewrite_rule),
)
.route(
"/rewrite-rules/{id}",
axum::routing::get(get_rewrite_rule)
.put(update_rewrite_rule)
.delete(delete_rewrite_rule),
)
}