Skip to content

Commit

Permalink
add the other content-type support for routing
Browse files Browse the repository at this point in the history
  • Loading branch information
yaojianpin committed Jun 6, 2023
1 parent fe96fff commit 872fb05
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 37 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
authors = ["yao <[email protected]>"]
edition = "2021"
name = "mock-server"
version = "1.0.1"
version = "1.1.0"

[dependencies]
axum = "0.5.13"
Expand All @@ -13,6 +13,7 @@ regex = "1.6.0"
serde = {version = "1.0.141", features = ["derive"]}
serde_json = "1.0.82"
tokio = {version = "1.20.1", features = ["full"]}
tower = "0.4.13"
tower-http = {version = "0.3.4", features = ["fs", "trace", "cors"]}
tracing = "0.1.36"
tracing-subscriber = {version = "0.3.15", features = ["registry", "fmt"]}
Expand Down
101 changes: 68 additions & 33 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use crate::{
models::{DataConfig, RoutingRule, Wrapper, WRAP_KEY_ERR, WRAP_KEY_OK},
models::{DataConfig, RoutingRule, RoutingValue, Wrapper, WRAP_KEY_ERR, WRAP_KEY_OK},
service::*,
util, Database, HashMap,
};
use axum::{
extract::{OriginalUri, Path, Query},
http::{Method, StatusCode},
body::Body,
extract::{FromRequest, Path, Query, RequestParts},
http::{Method, Request, StatusCode},
response::IntoResponse,
routing::{any, get, get_service},
Extension, Json, Router,
routing::{get, get_service},
Extension, Form, Json, Router,
};
use serde_json::Value;
use tower::service_fn;
use tower_http::services::ServeDir;

const DATA_QUERY_TPL: &str = "/api/([^/]*)$";
Expand Down Expand Up @@ -38,24 +40,51 @@ pub fn proxy(db: &Database) -> Router {
tracing::debug!("routing {} to {:?}", key, v);
let routing_value = v.clone();
let wrap = create_wrap(config, &routing_value.wrapping);
router = router.route(
key,
any(
|method: Method,
mut path: Path<HashMap<String, String>>,
query: Query<HashMap<String, String>>,
body: Json<Value>,
db: Extension<Database>,
wapper: Extension<Wrapper>,
OriginalUri(original_uri): OriginalUri| async move {
tracing::debug!(
"original_uri = {original_uri}, method={method} path={:?}, query={:?}, body={:?}",
path, query, body
);
router = router
.route(
key,
service_fn(|req: Request<Body>| async move {
let ex = req.extensions();
let db = Extension(ex.get::<Database>().cloned().unwrap());
let wrap = Extension(ex.get::<Wrapper>().cloned().unwrap());
let Extension(routing_value) =
Extension(ex.get::<RoutingValue>().cloned().unwrap());
let uri = req.uri();
tracing::info!("uri={}", uri);

let mut req_parts = RequestParts::new(req);

let query = Query::<HashMap<String, String>>::from_request(&mut req_parts)
.await
.unwrap();
let mut path = Path::<HashMap<String, String>>::from_request(&mut req_parts)
.await
.unwrap();

let mut body = Json(Value::Null);

// process form body and convert it to json format
if let Ok(Form(v)) =
Form::<Vec<(String, String)>>::from_request(&mut req_parts).await
{
let mut map = serde_json::Map::new();
for (key, value) in v {
map.insert(key, value.into());
}

body = Json(serde_json::Value::Object(map));
}

// process json body
if let Ok(v) = Json::<Value>::from_request(&mut req_parts).await {
body = v;
}

let method = req_parts.method();
// 检查规则
if let Err(err) = validate_rules(routing_value.rules, &path, &query, &body) {
return util::wrap_result(Err(err), Some(wapper.0)).into_response();
let res = util::wrap_result(Err(err), Some(wrap.0)).into_response();
return Ok(res);
}
// match the template
let re = regex::Regex::new(DATA_QUERY_TPL).unwrap();
Expand All @@ -66,13 +95,14 @@ pub fn proxy(db: &Database) -> Router {
}

let new_query = create_query(query, routing_value.query);
return query_data(path, Query(new_query), db.clone())
let res = query_data(path, Query(new_query), db.clone())
.await
.into_response();
return Ok(res);
}

let re = regex::Regex::new(DATA_ID_TPL).unwrap();
if let Some(cap) = re.captures(&routing_value.to) {
if let Some(cap) = re.captures(&routing_value.to) {
let data = cap.get(1).unwrap().as_str();
let id = cap.get(2).unwrap().as_str();
if !data.starts_with(":") {
Expand All @@ -82,19 +112,24 @@ pub fn proxy(db: &Database) -> Router {
if !id.starts_with(":") {
path.insert("id".to_string(), id.to_string());
}
return match method {
Method::GET => get_data(path, db, wapper).await.into_response(),
Method::POST => post_data(path, body, db, wapper).await.into_response(),
Method::PUT => put_data(path, body, db, wapper).await.into_response(),
Method::DELETE => delete_data(path, db, wapper).await.into_response(),
_ => (StatusCode::METHOD_NOT_ALLOWED, "method not support").into_response(),
}
let res = match method {
&Method::GET => get_data(path, db, wrap).await.into_response(),
&Method::POST => post_data(path, body, db, wrap).await.into_response(),
&Method::PUT => put_data(path, body, db, wrap).await.into_response(),
&Method::DELETE => delete_data(path, db, wrap).await.into_response(),
_ => (StatusCode::METHOD_NOT_ALLOWED, "method not support")
.into_response(),
};

return Ok(res);
}

(StatusCode::BAD_REQUEST, "bad request").into_response()
},
),
).layer(Extension(wrap))
let res = (StatusCode::BAD_REQUEST, "bad request").into_response();
Ok(res)
}),
)
.layer(Extension(wrap))
.layer(Extension(routing_value))
}

router
Expand Down
2 changes: 1 addition & 1 deletion src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub const WRAP_PAGE_PAGE: &str = "$page";
pub const WRAP_PAGE_SIZE: &str = "$size";
pub const WRAP_PAGE_ITEMS: &str = "$items";

pub use data_config::{DataConfig, RoutingRule};
pub use data_config::{DataConfig, RoutingRule, RoutingValue};
pub use named_query::NamedQuery;
use serde_json::Value;
pub type Wrapper = HashMap<String, Value>;
4 changes: 3 additions & 1 deletion static/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"config": {

"routing": {

"/fbpm_demo/api/expense/listByPageTask": {
"to": "/api/data2"
},
"/a/b/c/:id": {
"to": "/api/data/:id"
},
Expand Down

0 comments on commit 872fb05

Please sign in to comment.