feature/upstream-service #13

Merged
GW_MC merged 43 commits from feature/upstream-service into master 2026-01-01 10:49:32 +08:00
5 changed files with 70 additions and 1 deletions
Showing only changes of commit 35fadb46f6 - Show all commits

1
Cargo.lock generated
View File

@@ -5446,6 +5446,7 @@ dependencies = [
"sea-orm",
"serde",
"serde_json",
"serde_urlencoded",
"tempfile",
"tokio",
"tower",

View File

@@ -30,6 +30,7 @@ jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] }
uuid = { version = "1.19.0", features = ["v4", "serde", "fast-rng"] }
tower-http = { version = "0.6.8", features = ["cors"] }
reqwest = { version = "^0.12", features = ["json", "multipart", "stream"] }
serde_urlencoded = { version = "0.7.1" }
[dev-dependencies]
tempfile = "3"

View File

@@ -1,5 +1,6 @@
mod auth;
mod health;
mod helper;
mod openapi;
mod restricted;

View File

@@ -0,0 +1 @@
pub mod pagination;

View File

@@ -0,0 +1,65 @@
use axum::{
extract::FromRequestParts,
http::{StatusCode, request::Parts},
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
/// Pagination parameters for API requests
pub struct Pagination {
/// Page number (1-based)
pub page: u32,
/// Items per page
pub per_page: u32,
}
impl Default for Pagination {
fn default() -> Self {
Self {
page: 1,
per_page: 20,
}
}
}
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
/// Pagination information included in API responses
pub struct PaginationInfo {
/// Total number of items
pub total_items: u64,
/// Total number of pages
pub total_pages: u32,
/// Current page number
pub current_page: u32,
/// Items per page
pub per_page: u32,
}
/// Extractor for pagination parameters from query string
pub struct ExtractPagination(pub Pagination);
impl<S> FromRequestParts<S> for ExtractPagination
where
S: Send + Sync,
{
type Rejection = (StatusCode, &'static str);
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let query = parts.uri.query().unwrap_or("");
let pagination: Pagination = serde_urlencoded::from_str(query).unwrap_or_default();
// validation
if pagination.page == 0 {
return Err((StatusCode::BAD_REQUEST, "page must be greater than 0"));
}
if pagination.per_page < 1 || pagination.per_page > 100 {
return Err((
StatusCode::BAD_REQUEST,
"per_page must be between 1 and 100",
));
}
Ok(ExtractPagination(pagination))
}
}