Skip to content

Commit

Permalink
Extract handler mod
Browse files Browse the repository at this point in the history
  • Loading branch information
bouzuya committed Jan 12, 2024
1 parent 79574d5 commit 1fd5b42
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 74 deletions.
74 changes: 74 additions & 0 deletions backend/src/handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::{collections::HashSet, sync::Arc};

use axum::{
extract::{Path, State},
http::StatusCode,
routing, Json, Router,
};
use expo_push_notification_client::{Expo, ExpoClientOptions, ExpoPushMessage};
use tokio::sync::Mutex;

#[derive(Clone, Debug, Default)]
pub struct App {
pub expo_push_tokens: Arc<Mutex<HashSet<String>>>,
}

pub fn route(app: App) -> Router {
Router::new()
.route("/", routing::get(get_root))
.route("/expo_push_tokens", routing::post(create_expo_push_token))
.route(
"/expo_push_tokens/:expo_push_token",
routing::delete(delete_expo_push_token),
)
.route("/notifications", routing::post(create_notification))
.with_state(app)
}

#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct CreateExpoPushTokenRequestBody {
pub expo_push_token: String,
}

pub async fn create_expo_push_token(
State(App { expo_push_tokens }): State<App>,
Json(CreateExpoPushTokenRequestBody { expo_push_token }): Json<CreateExpoPushTokenRequestBody>,
) -> StatusCode {
let mut expo_push_tokens = expo_push_tokens.lock().await;
// TODO: already exists
expo_push_tokens.insert(expo_push_token);
StatusCode::CREATED
}

pub async fn delete_expo_push_token(
State(App { expo_push_tokens }): State<App>,
Path(expo_push_token): Path<String>,
) -> StatusCode {
let mut expo_push_tokens = expo_push_tokens.lock().await;
// TODO: not found
expo_push_tokens.remove(&expo_push_token);
StatusCode::NO_CONTENT
}

pub async fn create_notification(
State(App { expo_push_tokens }): State<App>,
) -> Result<StatusCode, StatusCode> {
let expo_client = Expo::new(ExpoClientOptions {
// TODO
access_token: None,
});
let expo_push_tokens = expo_push_tokens.lock().await;
expo_client
.send_push_notifications(
ExpoPushMessage::builder(expo_push_tokens.clone())
.build()
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?,
)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(StatusCode::CREATED)
}

pub async fn get_root() -> &'static str {
"OK"
}
80 changes: 6 additions & 74 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,77 +1,7 @@
use std::{collections::HashSet, sync::Arc};
mod handler;

use axum::{
extract::{Path, State},
http::StatusCode,
routing, Json, Router,
};
use expo_push_notification_client::{Expo, ExpoClientOptions, ExpoPushMessage};
use tokio::{net::TcpListener, sync::Mutex};

#[derive(Clone, Debug, Default)]
struct App {
expo_push_tokens: Arc<Mutex<HashSet<String>>>,
}

#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct CreateExpoPushTokenRequestBody {
expo_push_token: String,
}

async fn create_expo_push_token(
State(App { expo_push_tokens }): State<App>,
Json(CreateExpoPushTokenRequestBody { expo_push_token }): Json<CreateExpoPushTokenRequestBody>,
) -> StatusCode {
let mut expo_push_tokens = expo_push_tokens.lock().await;
// TODO: already exists
expo_push_tokens.insert(expo_push_token);
StatusCode::CREATED
}

async fn delete_expo_push_token(
State(App { expo_push_tokens }): State<App>,
Path(expo_push_token): Path<String>,
) -> StatusCode {
let mut expo_push_tokens = expo_push_tokens.lock().await;
// TODO: not found
expo_push_tokens.remove(&expo_push_token);
StatusCode::NO_CONTENT
}

async fn create_notification(
State(App { expo_push_tokens }): State<App>,
) -> Result<StatusCode, StatusCode> {
let expo_client = Expo::new(ExpoClientOptions {
// TODO
access_token: None,
});
let expo_push_tokens = expo_push_tokens.lock().await;
expo_client
.send_push_notifications(
ExpoPushMessage::builder(expo_push_tokens.clone())
.build()
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?,
)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(StatusCode::CREATED)
}

async fn get_root() -> &'static str {
"OK"
}

fn route(app: App) -> Router {
Router::new()
.route("/", routing::get(get_root))
.route("/expo_push_tokens", routing::post(create_expo_push_token))
.route(
"/expo_push_tokens/:expo_push_token",
routing::delete(delete_expo_push_token),
)
.route("/notifications", routing::post(create_notification))
.with_state(app)
}
use handler::{route, App};
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
Expand All @@ -85,11 +15,13 @@ mod tests {
use axum::{
async_trait,
body::Body,
http::{header::CONTENT_TYPE, Request},
http::{header::CONTENT_TYPE, Request, StatusCode},
response::Response,
};
use tower::ServiceExt;

use crate::handler::CreateExpoPushTokenRequestBody;

use super::*;

#[tokio::test]
Expand Down

0 comments on commit 1fd5b42

Please sign in to comment.