mirror of
https://github.com/deps-rs/deps.rs.git
synced 2024-11-22 10:26:30 +00:00
implement api routing
This commit is contained in:
parent
2ce0218218
commit
28f5cf7ba2
3 changed files with 91 additions and 39 deletions
|
@ -7,6 +7,7 @@ authors = ["Sam Rijs <srijs@airpost.net>"]
|
||||||
futures = "0.1.18"
|
futures = "0.1.18"
|
||||||
hyper = "0.11.15"
|
hyper = "0.11.15"
|
||||||
hyper-tls = "0.1.2"
|
hyper-tls = "0.1.2"
|
||||||
|
route-recognizer = "0.1.12"
|
||||||
semver = { version = "0.9.0", features = ["serde"] }
|
semver = { version = "0.9.0", features = ["serde"] }
|
||||||
serde = "1.0.27"
|
serde = "1.0.27"
|
||||||
serde_derive = "1.0.27"
|
serde_derive = "1.0.27"
|
||||||
|
|
67
src/api.rs
67
src/api.rs
|
@ -1,8 +1,10 @@
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::{Future, future};
|
use futures::{Future, IntoFuture, future};
|
||||||
use hyper::{Error as HyperError, Request, Response, StatusCode};
|
use hyper::{Error as HyperError, Method, Request, Response, StatusCode};
|
||||||
use hyper::header::ContentType;
|
use hyper::header::ContentType;
|
||||||
|
use route_recognizer::{Params, Router};
|
||||||
use semver::{Version, VersionReq};
|
use semver::{Version, VersionReq};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
@ -11,8 +13,23 @@ use tokio_service::Service;
|
||||||
use ::models::repo::RepoPath;
|
use ::models::repo::RepoPath;
|
||||||
use ::engine::Engine;
|
use ::engine::Engine;
|
||||||
|
|
||||||
|
enum Route {
|
||||||
|
AnalyzeDependencies
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Api {
|
pub struct Api {
|
||||||
pub engine: Engine
|
engine: Engine,
|
||||||
|
router: Arc<Router<Route>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
pub fn new(engine: Engine) -> Api {
|
||||||
|
let mut router = Router::new();
|
||||||
|
router.add("/api/v1/analyze/:site/:qual/:name", Route::AnalyzeDependencies);
|
||||||
|
|
||||||
|
Api { engine, router: Arc::new(router) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
@ -38,10 +55,41 @@ impl Service for Api {
|
||||||
type Future = Box<Future<Item=Response, Error=HyperError>>;
|
type Future = Box<Future<Item=Response, Error=HyperError>>;
|
||||||
|
|
||||||
fn call(&self, req: Request) -> Self::Future {
|
fn call(&self, req: Request) -> Self::Future {
|
||||||
let repo_path = RepoPath::from_parts("github.com", "hyperium", "hyper").unwrap();
|
if let Ok(route_match) = self.router.recognize(req.uri().path()) {
|
||||||
|
match route_match.handler {
|
||||||
|
&Route::AnalyzeDependencies => {
|
||||||
|
if *req.method() == Method::Get {
|
||||||
|
return Box::new(self.analyze_dependencies(req, route_match.params));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let future = self.engine.analyze_dependencies(repo_path).then(|result| {
|
let mut response = Response::new();
|
||||||
match result {
|
response.set_status(StatusCode::NotFound);
|
||||||
|
Box::new(future::ok(response))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
fn analyze_dependencies<'r>(&self, _req: Request, params: Params) -> impl Future<Item=Response, Error=HyperError> {
|
||||||
|
let engine = self.engine.clone();
|
||||||
|
|
||||||
|
let site = params.find("site").expect("route param 'site' not found");
|
||||||
|
let qual = params.find("qual").expect("route param 'qual' not found");
|
||||||
|
let name = params.find("name").expect("route param 'name' not found");
|
||||||
|
|
||||||
|
RepoPath::from_parts(site, qual, name).into_future().then(move |repo_path_result| {
|
||||||
|
match repo_path_result {
|
||||||
|
Err(err) => {
|
||||||
|
let mut response = Response::new();
|
||||||
|
response.set_status(StatusCode::BadRequest);
|
||||||
|
response.set_body(format!("{:?}", err));
|
||||||
|
future::Either::A(future::ok(response))
|
||||||
|
},
|
||||||
|
Ok(repo_path) => {
|
||||||
|
future::Either::B(engine.analyze_dependencies(repo_path).then(|analyze_result| {
|
||||||
|
match analyze_result {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut response = Response::new();
|
let mut response = Response::new();
|
||||||
response.set_status(StatusCode::InternalServerError);
|
response.set_status(StatusCode::InternalServerError);
|
||||||
|
@ -75,8 +123,9 @@ impl Service for Api {
|
||||||
future::Either::B(future::ok(response))
|
future::Either::B(future::ok(response))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}))
|
||||||
|
}
|
||||||
Box::new(future)
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate hyper_tls;
|
extern crate hyper_tls;
|
||||||
|
extern crate route_recognizer;
|
||||||
extern crate semver;
|
extern crate semver;
|
||||||
#[macro_use] extern crate serde_derive;
|
#[macro_use] extern crate serde_derive;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
@ -61,9 +62,10 @@ fn main() {
|
||||||
logger: logger.clone()
|
logger: logger.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let serve = http.serve_addr_handle(&addr, &handle, move || {
|
let api = Api::new(engine);
|
||||||
Ok(Api { engine: engine.clone() })
|
|
||||||
}).expect("failed to bind server");
|
let serve = http.serve_addr_handle(&addr, &handle, move || Ok(api.clone()))
|
||||||
|
.expect("failed to bind server");
|
||||||
|
|
||||||
let serving = serve.for_each(move |conn| {
|
let serving = serve.for_each(move |conn| {
|
||||||
let conn_logger = logger.clone();
|
let conn_logger = logger.clone();
|
||||||
|
|
Loading…
Reference in a new issue