Continue adding in more API routes
This commit is contained in:
Nathan Sobo 2022-04-24 18:02:14 -06:00
parent e30a3956d6
commit cb9d608e53
4 changed files with 93 additions and 80 deletions

1
Cargo.lock generated
View File

@ -953,6 +953,7 @@ dependencies = [
"tokio", "tokio",
"tokio-tungstenite", "tokio-tungstenite",
"toml", "toml",
"tower",
"util", "util",
"workspace", "workspace",
] ]

View File

@ -20,7 +20,7 @@ util = { path = "../util" }
anyhow = "1.0.40" anyhow = "1.0.40"
async-trait = "0.1.50" async-trait = "0.1.50"
async-tungstenite = "0.16" async-tungstenite = "0.16"
axum = "0.5" axum = { version = "0.5", features = ["json"] }
base64 = "0.13" base64 = "0.13"
envy = "0.4.2" envy = "0.4.2"
env_logger = "0.8" env_logger = "0.8"
@ -36,6 +36,7 @@ serde_json = "1.0"
sha-1 = "0.9" sha-1 = "0.9"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
tokio-tungstenite = "0.17" tokio-tungstenite = "0.17"
tower = "0.4"
time = "0.2" time = "0.2"
toml = "0.5.8" toml = "0.5.8"

View File

@ -1,20 +1,33 @@
// use crate::{auth, db::UserId, AppState, Request, RequestExt as _}; use crate::{
use anyhow::Result; db::{Db, User, UserId},
AppState, Result,
};
use anyhow::anyhow;
use axum::{ use axum::{
body::Body, body::Body,
http::{Request, Response, StatusCode}, extract::Path,
routing::get, http::{Request, StatusCode},
Router, response::{IntoResponse, Response},
routing::{get, put},
Json, Router,
}; };
use serde::Deserialize; use serde::Deserialize;
use serde_json::json;
use std::sync::Arc; use std::sync::Arc;
use crate::AppState; pub fn add_routes(router: Router<Body>, app: Arc<AppState>) -> Router<Body> {
// use surf::StatusCode; router
.route("/users", {
pub fn add_routes(router: Router<Body>) -> Router<Body> { let app = app.clone();
router.route("/users", get(get_users)) get(move |req| get_users(req, app))
})
.route("/users", {
let app = app.clone();
get(move |params| create_user(params, app))
})
.route("/users/:id", {
let app = app.clone();
put(move |user_id, params| update_user(user_id, params, app))
})
} }
// pub fn add_routes(app: &mut tide::Server<Arc<AppState>>) { // pub fn add_routes(app: &mut tide::Server<Arc<AppState>>) {
@ -27,65 +40,48 @@ pub fn add_routes(router: Router<Body>) -> Router<Body> {
// .post(create_access_token); // .post(create_access_token);
// } // }
async fn get_users(request: Request<Body>) -> Result<Response<Body>, (StatusCode, String)> { async fn get_users(request: Request<Body>, app: Arc<AppState>) -> Result<Json<Vec<User>>> {
// request.require_token().await?; // request.require_token().await?;
// let users = request.db().get_all_users().await?; let users = app.db.get_all_users().await?;
Ok(Json(users))
// Body::from
// let body = "Hello World";
// Ok(Response::builder()
// .header(CONTENT_LENGTH, body.len() as u64)
// .header(CONTENT_TYPE, "text/plain")
// .body(Body::from(body))?)
// Ok(tide::Response::builder(StatusCode::Ok)
// .body(tide::Body::from_json(&users)?)
// .build())
todo!()
} }
// async fn get_user(request: Request) -> tide::Result { #[derive(Deserialize)]
// request.require_token().await?; struct CreateUser {
github_login: String,
admin: bool,
}
// let user = request async fn create_user(Json(params): Json<CreateUser>, app: Arc<AppState>) -> Result<Json<User>> {
// .db() let user_id = app
// .get_user_by_github_login(request.param("github_login")?) .db
// .await? .create_user(&params.github_login, params.admin)
// .ok_or_else(|| surf::Error::from_str(404, "user not found"))?; .await?;
// Ok(tide::Response::builder(StatusCode::Ok) let user = app
// .body(tide::Body::from_json(&user)?) .db
// .build()) .get_user_by_id(user_id)
// } .await?
.ok_or_else(|| anyhow!("couldn't find the user we just created"))?;
// async fn create_user(mut request: Request) -> tide::Result { Ok(Json(user))
// request.require_token().await?; }
// #[derive(Deserialize)] #[derive(Deserialize)]
// struct Params { struct UpdateUser {
// github_login: String, admin: bool,
// admin: bool, }
// }
// let params = request.body_json::<Params>().await?;
// let user_id = request async fn update_user(
// .db() Path(user_id): Path<i32>,
// .create_user(&params.github_login, params.admin) Json(params): Json<UpdateUser>,
// .await?; app: Arc<AppState>,
) -> Result<impl IntoResponse> {
// let user = request.db().get_user_by_id(user_id).await?.ok_or_else(|| { let user_id = UserId(user_id);
// surf::Error::from_str( app.db.set_user_is_admin(user_id, params.admin).await?;
// StatusCode::InternalServerError, Ok(())
// "couldn't find the user we just created", }
// )
// })?;
// Ok(tide::Response::builder(StatusCode::Ok)
// .body(tide::Body::from_json(&user)?)
// .build())
// }
// async fn update_user(mut request: Request) -> tide::Result { // async fn update_user(mut request: Request) -> tide::Result {
// request.require_token().await?; // request.require_token().await?;
@ -94,13 +90,6 @@ async fn get_users(request: Request<Body>) -> Result<Response<Body>, (StatusCode
// struct Params { // struct Params {
// admin: bool, // admin: bool,
// } // }
// let user_id = UserId(
// request
// .param("id")?
// .parse::<i32>()
// .map_err(|error| surf::Error::from_str(StatusCode::BadRequest, error.to_string()))?,
// );
// let params = request.body_json::<Params>().await?;
// request // request
// .db() // .db()

View File

@ -5,8 +5,7 @@ mod env;
mod rpc; mod rpc;
use ::rpc::Peer; use ::rpc::Peer;
use anyhow::Result; use axum::{body::Body, http::StatusCode, response::IntoResponse, Router};
use axum::{body::Body, http::StatusCode, Router};
use db::{Db, PostgresDb}; use db::{Db, PostgresDb};
use serde::Deserialize; use serde::Deserialize;
@ -76,24 +75,16 @@ async fn main() -> Result<()> {
Ok(()) Ok(())
} }
async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) {
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Something went wrong: {}", err),
)
}
pub async fn run_server( pub async fn run_server(
state: Arc<AppState>, state: Arc<AppState>,
peer: Arc<Peer>, peer: Arc<Peer>,
listener: TcpListener, listener: TcpListener,
) -> Result<()> { ) -> Result<()> {
let app = Router::<Body>::new(); let app = Router::<Body>::new();
// TODO: Assign app state to request somehow
// TODO: Compression on API routes? // TODO: Compression on API routes?
// TODO: Authenticate API routes. // TODO: Authenticate API routes.
let app = api::add_routes(app); let app = api::add_routes(app, state);
// TODO: Add rpc routes // TODO: Add rpc routes
axum::Server::from_tcp(listener)? axum::Server::from_tcp(listener)?
@ -102,3 +93,34 @@ pub async fn run_server(
Ok(()) Ok(())
} }
type Result<T> = std::result::Result<T, Error>;
struct Error(anyhow::Error);
impl<E> From<E> for Error
where
E: Into<anyhow::Error>,
{
fn from(error: E) -> Self {
Self(error.into())
}
}
impl IntoResponse for Error {
fn into_response(self) -> axum::response::Response {
(StatusCode::INTERNAL_SERVER_ERROR, format!("{}", &self.0)).into_response()
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}