Skip to content

Commit

Permalink
Add request method support
Browse files Browse the repository at this point in the history
  • Loading branch information
ztroop committed Feb 6, 2024
1 parent f960614 commit 620ea11
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 36 deletions.
4 changes: 2 additions & 2 deletions examples/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
- name: "Example Endpoint 1"
endpoint: "/example1"
method: "POST"
data:
message: "This is the first example response."
details:
Expand All @@ -11,6 +12,7 @@

- name: "Example Endpoint 2"
endpoint: "/example2"
method: "POST"
data:
success: true
payload:
Expand All @@ -20,6 +22,4 @@

- name: "Not Found Example"
endpoint: "/notfound"
data:
error: "Resource not found."
status: 404
30 changes: 30 additions & 0 deletions src/handlers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use axum::response::IntoResponse;
use axum::{http::StatusCode, response::Json};
use serde_json::Value;
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;

// Default handler for no YAML configuration
pub async fn default_handler() -> &'static str {
"OK"
}

// Handler for custom route
pub async fn handle_custom_route(
data: Arc<Value>,
status: StatusCode,
headers: Arc<HashMap<String, String>>,
) -> impl axum::response::IntoResponse {
let mut response = axum::response::Response::new(Json(data.as_ref().clone()).into_response());
*response.status_mut() = status;

for (key, value) in headers.as_ref() {
response.headers_mut().insert(
axum::http::header::HeaderName::from_str(key).unwrap(),
axum::http::header::HeaderValue::from_str(value).unwrap(),
);
}

response
}
18 changes: 18 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[macro_export]
macro_rules! route_with_method {
($app:expr, $method:expr, $endpoint:expr, $handler:expr) => {
match $method {
$crate::structs::HttpMethod::Get => $app.route($endpoint, axum::routing::get($handler)),
$crate::structs::HttpMethod::Post => {
$app.route($endpoint, axum::routing::post($handler))
}
$crate::structs::HttpMethod::Put => $app.route($endpoint, axum::routing::put($handler)),
$crate::structs::HttpMethod::Patch => {
$app.route($endpoint, axum::routing::patch($handler))
}
$crate::structs::HttpMethod::Delete => {
$app.route($endpoint, axum::routing::delete($handler))
}
}
};
}
52 changes: 18 additions & 34 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use axum::response::IntoResponse;
use axum::{http::StatusCode, response::Json, routing::get, Router};
use axum::{http::StatusCode, Router};
use clap::Parser;
use serde_json::Value;
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;
use tower_http::trace::{self, TraceLayer};
use tracing::Level;

mod handlers;
mod macros;
mod structs;

#[tokio::main]
Expand All @@ -33,16 +33,24 @@ async fn main() {
let route_headers =
Arc::new(config.headers.unwrap_or(HashMap::<String, String>::new()));
let status_code = StatusCode::from_u16(config.status).unwrap_or(StatusCode::OK);
app = app.route(
&config.endpoint,
get(move || {
handle_custom_route(route_data.clone(), status_code, route_headers.clone())
}),
);
app = route_with_method!(app, config.method, &config.endpoint, move || {
handlers::handle_custom_route(
route_data.clone(),
status_code,
route_headers.clone(),
)
});
}
} else {
// Default behavior
app = app.route("/", get(default_handler));
app = app.route(
"/*path",
axum::routing::get(handlers::default_handler)
.post(handlers::default_handler)
.put(handlers::default_handler)
.patch(handlers::default_handler)
.delete(handlers::default_handler),
);
}

// Add middleware
Expand All @@ -65,27 +73,3 @@ fn load_yaml_config(file_path: &str) -> Vec<structs::EndpointConfig> {
let file_content = std::fs::read_to_string(file_path).expect("Unable to read file");
serde_yaml::from_str(&file_content).expect("Unable to parse YAML")
}

// Default handler for no YAML configuration
async fn default_handler() -> &'static str {
"OK"
}

// Handler for custom route
async fn handle_custom_route(
data: Arc<Value>,
status: StatusCode,
headers: Arc<HashMap<String, String>>,
) -> impl axum::response::IntoResponse {
let mut response = axum::response::Response::new(Json(data.as_ref().clone()).into_response());
*response.status_mut() = status;

for (key, value) in headers.as_ref() {
response.headers_mut().insert(
axum::http::header::HeaderName::from_str(key).unwrap(),
axum::http::header::HeaderValue::from_str(value).unwrap(),
);
}

response
}
13 changes: 13 additions & 0 deletions src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,20 @@ pub struct Args {
pub struct EndpointConfig {
pub name: String,
pub endpoint: String,
#[serde(default)]
pub method: HttpMethod,
pub data: Option<serde_json::Value>,
pub status: u16,
pub headers: Option<HashMap<String, String>>,
}

#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(rename_all = "UPPERCASE")]
pub enum HttpMethod {
#[default]
Get,
Post,
Put,
Delete,
Patch,
}

0 comments on commit 620ea11

Please sign in to comment.