Add ResponseBuilder to rest_api
This commit is contained in:
parent
d05c2d4110
commit
6c50758bdf
@ -14,9 +14,12 @@ store = { path = "../store" }
|
|||||||
version = { path = "../version" }
|
version = { path = "../version" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "^1.0"
|
serde_json = "^1.0"
|
||||||
|
serde_yaml = "0.8"
|
||||||
slog = "^2.2.3"
|
slog = "^2.2.3"
|
||||||
slog-term = "^2.4.0"
|
slog-term = "^2.4.0"
|
||||||
slog-async = "^2.3.0"
|
slog-async = "^2.3.0"
|
||||||
|
eth2_ssz = { path = "../../eth2/utils/ssz" }
|
||||||
|
eth2_ssz_derive = { path = "../../eth2/utils/ssz_derive" }
|
||||||
state_processing = { path = "../../eth2/state_processing" }
|
state_processing = { path = "../../eth2/state_processing" }
|
||||||
types = { path = "../../eth2/types" }
|
types = { path = "../../eth2/types" }
|
||||||
clap = "2.32.0"
|
clap = "2.32.0"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use super::{success_response, ApiResult};
|
use super::{success_response, ApiResult, ResponseBuilder};
|
||||||
use crate::{helpers::*, ApiError, UrlQuery};
|
use crate::{helpers::*, ApiError, UrlQuery};
|
||||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||||
use hyper::{Body, Request};
|
use hyper::{Body, Request};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use ssz_derive::Encode;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use store::Store;
|
use store::Store;
|
||||||
use types::{BeaconBlock, BeaconState, EthSpec, Hash256, Slot};
|
use types::{BeaconBlock, BeaconState, EthSpec, Hash256, Slot};
|
||||||
@ -33,7 +34,7 @@ pub fn get_head<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
|
|||||||
Ok(success_response(Body::from(json)))
|
Ok(success_response(Body::from(json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize, Encode)]
|
||||||
#[serde(bound = "T: EthSpec")]
|
#[serde(bound = "T: EthSpec")]
|
||||||
pub struct BlockResponse<T: EthSpec> {
|
pub struct BlockResponse<T: EthSpec> {
|
||||||
pub root: Hash256,
|
pub root: Hash256,
|
||||||
@ -77,11 +78,7 @@ pub fn get_block<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
|
|||||||
beacon_block: block,
|
beacon_block: block,
|
||||||
};
|
};
|
||||||
|
|
||||||
let json: String = serde_json::to_string(&response).map_err(|e| {
|
ResponseBuilder::new(&req).body(&response)
|
||||||
ApiError::ServerError(format!("Unable to serialize BlockResponse: {:?}", e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(success_response(Body::from(json)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HTTP handler to return a `BeaconBlock` root at a given `slot`.
|
/// HTTP handler to return a `BeaconBlock` root at a given `slot`.
|
||||||
@ -104,7 +101,7 @@ pub fn get_block_root<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiR
|
|||||||
Ok(success_response(Body::from(json)))
|
Ok(success_response(Body::from(json)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize, Encode)]
|
||||||
#[serde(bound = "T: EthSpec")]
|
#[serde(bound = "T: EthSpec")]
|
||||||
pub struct StateResponse<T: EthSpec> {
|
pub struct StateResponse<T: EthSpec> {
|
||||||
pub root: Hash256,
|
pub root: Hash256,
|
||||||
@ -144,11 +141,7 @@ pub fn get_state<T: BeaconChainTypes + 'static>(req: Request<Body>) -> ApiResult
|
|||||||
beacon_state: state,
|
beacon_state: state,
|
||||||
};
|
};
|
||||||
|
|
||||||
let json: String = serde_json::to_string(&response).map_err(|e| {
|
ResponseBuilder::new(&req).body(&response)
|
||||||
ApiError::ServerError(format!("Unable to serialize StateResponse: {:?}", e))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(success_response(Body::from(json)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HTTP handler to return a `BeaconState` root at a given `slot`.
|
/// HTTP handler to return a `BeaconState` root at a given `slot`.
|
||||||
|
@ -8,6 +8,7 @@ mod helpers;
|
|||||||
mod metrics;
|
mod metrics;
|
||||||
mod network;
|
mod network;
|
||||||
mod node;
|
mod node;
|
||||||
|
mod response_builder;
|
||||||
mod spec;
|
mod spec;
|
||||||
mod url_query;
|
mod url_query;
|
||||||
mod validator;
|
mod validator;
|
||||||
@ -18,6 +19,7 @@ use eth2_config::Eth2Config;
|
|||||||
use hyper::rt::Future;
|
use hyper::rt::Future;
|
||||||
use hyper::service::service_fn_ok;
|
use hyper::service::service_fn_ok;
|
||||||
use hyper::{Body, Method, Response, Server, StatusCode};
|
use hyper::{Body, Method, Response, Server, StatusCode};
|
||||||
|
use response_builder::ResponseBuilder;
|
||||||
use slog::{info, o, warn};
|
use slog::{info, o, warn};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
50
beacon_node/rest_api/src/response_builder.rs
Normal file
50
beacon_node/rest_api/src/response_builder.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use super::{ApiError, ApiResult};
|
||||||
|
use http::header;
|
||||||
|
use hyper::{Body, Request, Response, StatusCode};
|
||||||
|
use serde::Serialize;
|
||||||
|
use ssz::Encode;
|
||||||
|
|
||||||
|
pub enum Encoding {
|
||||||
|
JSON,
|
||||||
|
SSZ,
|
||||||
|
YAML,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ResponseBuilder {
|
||||||
|
encoding: Encoding,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseBuilder {
|
||||||
|
pub fn new(req: &Request<Body>) -> Self {
|
||||||
|
let encoding = match req.headers().get(header::CONTENT_TYPE) {
|
||||||
|
Some(h) if h == "application/ssz" => Encoding::SSZ,
|
||||||
|
Some(h) if h == "application/yaml" => Encoding::YAML,
|
||||||
|
_ => Encoding::JSON,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self { encoding }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn body<T: Serialize + Encode>(self, item: &T) -> ApiResult {
|
||||||
|
let body: Body = match self.encoding {
|
||||||
|
Encoding::JSON => Body::from(serde_json::to_string(&item).map_err(|e| {
|
||||||
|
ApiError::ServerError(format!(
|
||||||
|
"Unable to serialize response body as JSON: {:?}",
|
||||||
|
e
|
||||||
|
))
|
||||||
|
})?),
|
||||||
|
Encoding::SSZ => Body::from(item.as_ssz_bytes()),
|
||||||
|
Encoding::YAML => Body::from(serde_yaml::to_string(&item).map_err(|e| {
|
||||||
|
ApiError::ServerError(format!(
|
||||||
|
"Unable to serialize response body as YAML: {:?}",
|
||||||
|
e
|
||||||
|
))
|
||||||
|
})?),
|
||||||
|
};
|
||||||
|
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::OK)
|
||||||
|
.body(Body::from(body))
|
||||||
|
.map_err(|e| ApiError::ServerError(format!("Failed to build response: {:?}", e)))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user