add output formatter
This commit is contained in:
parent
03862a2eeb
commit
1571873d7b
|
@ -23,6 +23,7 @@ pub mod api {
|
||||||
|
|
||||||
pub mod server {
|
pub mod server {
|
||||||
|
|
||||||
|
pub mod formatter;
|
||||||
pub mod rest;
|
pub mod rest;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
use failure::*;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
pub struct OutputFormatter {
|
||||||
|
|
||||||
|
pub format_result: fn(data: &Value) -> (Vec<u8>, &'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn json_format_result(data: &Value) -> (Vec<u8>, &'static str) {
|
||||||
|
|
||||||
|
let content_type = "application/json;charset=UTF-8";
|
||||||
|
|
||||||
|
let result = json!({
|
||||||
|
"data": data
|
||||||
|
});
|
||||||
|
|
||||||
|
// todo: set result.total result.changes
|
||||||
|
|
||||||
|
let json_str = result.to_string();
|
||||||
|
|
||||||
|
let raw = json_str.into_bytes();
|
||||||
|
|
||||||
|
(raw, content_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static JSON_FORMATTER: OutputFormatter = OutputFormatter {
|
||||||
|
format_result: json_format_result,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
fn extjs_format_result(data: &Value) -> (Vec<u8>, &'static str) {
|
||||||
|
|
||||||
|
let content_type = "application/json;charset=UTF-8";
|
||||||
|
|
||||||
|
let result = json!({
|
||||||
|
"data": data,
|
||||||
|
"success": true
|
||||||
|
});
|
||||||
|
|
||||||
|
// todo: set result.total result.changes
|
||||||
|
|
||||||
|
let json_str = result.to_string();
|
||||||
|
|
||||||
|
let raw = json_str.into_bytes();
|
||||||
|
|
||||||
|
(raw, content_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static EXTJS_FORMATTER: OutputFormatter = OutputFormatter {
|
||||||
|
format_result: extjs_format_result,
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::api::schema::*;
|
use crate::api::schema::*;
|
||||||
use crate::api::router::*;
|
use crate::api::router::*;
|
||||||
use crate::api::config::*;
|
use crate::api::config::*;
|
||||||
|
use super::formatter::*;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -66,7 +67,7 @@ impl Service for ApiService {
|
||||||
match result {
|
match result {
|
||||||
Ok(res) => Ok::<_, hyper::Error>(res),
|
Ok(res) => Ok::<_, hyper::Error>(res),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if let Some(apierr) = err.downcast_ref::<HttpError>() {
|
if let Some(apierr) = err.downcast_ref::<HttpError>() {
|
||||||
let mut resp = Response::new(Body::from(apierr.message.clone()));
|
let mut resp = Response::new(Body::from(apierr.message.clone()));
|
||||||
*resp.status_mut() = apierr.code;
|
*resp.status_mut() = apierr.code;
|
||||||
Ok(resp)
|
Ok(resp)
|
||||||
|
@ -140,6 +141,7 @@ fn get_request_parameters_async(
|
||||||
|
|
||||||
if let Some(query_str) = parts.uri.query() {
|
if let Some(query_str) = parts.uri.query() {
|
||||||
for (k, v) in form_urlencoded::parse(query_str.as_bytes()).into_owned() {
|
for (k, v) in form_urlencoded::parse(query_str.as_bytes()).into_owned() {
|
||||||
|
if k == "_dc" { continue; } // skip extjs "disable cache" parameter
|
||||||
param_list.push((k, v));
|
param_list.push((k, v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +161,7 @@ fn get_request_parameters_async(
|
||||||
|
|
||||||
fn handle_sync_api_request(
|
fn handle_sync_api_request(
|
||||||
info: &'static ApiMethod,
|
info: &'static ApiMethod,
|
||||||
|
formatter: &'static OutputFormatter,
|
||||||
parts: Parts,
|
parts: Parts,
|
||||||
req_body: Body,
|
req_body: Body,
|
||||||
uri_param: HashMap<String, String>,
|
uri_param: HashMap<String, String>,
|
||||||
|
@ -185,15 +188,16 @@ fn handle_sync_api_request(
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
|
|
||||||
}).then(|result| {
|
}).then(move |result| {
|
||||||
match result {
|
match result {
|
||||||
Ok(ref value) => {
|
Ok(ref value) => {
|
||||||
let json_str = value.to_string();
|
|
||||||
|
let (raw, content_type) = (formatter.format_result)(value);
|
||||||
|
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
.header(header::CONTENT_TYPE, "application/json")
|
.header(header::CONTENT_TYPE, content_type)
|
||||||
.body(Body::from(json_str))?)
|
.body(Body::from(raw))?)
|
||||||
}
|
}
|
||||||
Err(err) => Err(http_err!(BAD_REQUEST, err.to_string()))
|
Err(err) => Err(http_err!(BAD_REQUEST, err.to_string()))
|
||||||
}
|
}
|
||||||
|
@ -374,15 +378,19 @@ pub fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> BoxFut {
|
||||||
println!("GOT API REQUEST");
|
println!("GOT API REQUEST");
|
||||||
if comp_len >= 2 {
|
if comp_len >= 2 {
|
||||||
let format = components[1];
|
let format = components[1];
|
||||||
if format != "json" {
|
let formatter = match format {
|
||||||
return Box::new(future::err(http_err!(BAD_REQUEST, format!("Unsupported output format '{}'.", format))))
|
"json" => &JSON_FORMATTER,
|
||||||
}
|
"extjs" => &EXTJS_FORMATTER,
|
||||||
|
_ => {
|
||||||
|
return Box::new(future::err(http_err!(BAD_REQUEST, format!("Unsupported output format '{}'.", format))));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut uri_param = HashMap::new();
|
let mut uri_param = HashMap::new();
|
||||||
|
|
||||||
if let Some(api_method) = api.find_method(&components[2..], method, &mut uri_param) {
|
if let Some(api_method) = api.find_method(&components[2..], method, &mut uri_param) {
|
||||||
// fixme: handle auth
|
// fixme: handle auth
|
||||||
return handle_sync_api_request(api_method, parts, body, uri_param);
|
return handle_sync_api_request(api_method, formatter, parts, body, uri_param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue