consolidate API routes

Signed-off-by: Xe Iaso <me@christine.website>
This commit is contained in:
Cadey Ratio 2022-07-10 09:58:57 -04:00
parent 18ae8a01f8
commit b32f5a25af
6 changed files with 85 additions and 82 deletions

78
src/handlers/api.rs Normal file
View File

@ -0,0 +1,78 @@
use crate::{
app::{config::Job, State},
handlers::Result,
post::Post,
};
use axum::extract::{Extension, Json, Path};
use lazy_static::lazy_static;
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
use std::sync::Arc;
lazy_static! {
static ref BLOG: IntCounterVec = register_int_counter_vec!(
opts!("blogpost_json_hits", "Number of hits to blogposts"),
&["name"]
)
.unwrap();
static ref TALK: IntCounterVec = register_int_counter_vec!(
opts!("talks_json_hits", "Number of hits to talks images"),
&["name"]
)
.unwrap();
}
#[axum_macros::debug_handler]
#[instrument(skip(state))]
pub async fn salary_transparency(Extension(state): Extension<Arc<State>>) -> Json<Vec<Job>> {
super::HIT_COUNTER
.with_label_values(&["salary_transparency_json"])
.inc();
Json(state.clone().cfg.clone().job_history.clone())
}
#[instrument(skip(state))]
pub async fn blog(
Path(name): Path<String>,
Extension(state): Extension<Arc<State>>,
) -> Result<Json<xe_jsonfeed::Item>> {
let mut want: Option<Post> = None;
let want_link = format!("blog/{}", name);
for post in &state.blog {
if post.link == want_link {
want = Some(post.clone());
}
}
match want {
None => Err(super::Error::PostNotFound(name)),
Some(post) => {
BLOG.with_label_values(&[name.clone().as_str()]).inc();
Ok(Json(post.into()))
}
}
}
#[instrument(skip(state))]
pub async fn talk(
Path(name): Path<String>,
Extension(state): Extension<Arc<State>>,
) -> Result<Json<xe_jsonfeed::Item>> {
let mut want: Option<Post> = None;
let want_link = format!("talks/{}", name);
for post in &state.talks {
if post.link == want_link {
want = Some(post.clone());
}
}
match want {
None => Err(super::Error::PostNotFound(name)),
Some(post) => {
TALK.with_label_values(&[name.clone().as_str()]).inc();
Ok(Json(post.into()))
}
}
}

View File

@ -3,7 +3,6 @@ use crate::{app::State, post::Post, templates};
use axum::{ use axum::{
extract::{Extension, Path}, extract::{Extension, Path},
response::Html, response::Html,
Json,
}; };
use http::HeaderMap; use http::HeaderMap;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -17,11 +16,6 @@ lazy_static! {
&["name"] &["name"]
) )
.unwrap(); .unwrap();
static ref HIT_COUNTER_JSON: IntCounterVec = register_int_counter_vec!(
opts!("blogpost_json_hits", "Number of hits to blogposts"),
&["name"]
)
.unwrap();
} }
#[instrument(skip(state))] #[instrument(skip(state))]
@ -114,28 +108,3 @@ pub async fn post_view(
} }
} }
} }
#[instrument(skip(state))]
pub async fn post_json(
Path(name): Path<String>,
Extension(state): Extension<Arc<State>>,
) -> Result<Json<xe_jsonfeed::Item>> {
let mut want: Option<Post> = None;
let want_link = format!("blog/{}", name);
for post in &state.blog {
if post.link == want_link {
want = Some(post.clone());
}
}
match want {
None => Err(super::Error::PostNotFound(name)),
Some(post) => {
HIT_COUNTER_JSON
.with_label_values(&[name.clone().as_str()])
.inc();
Ok(Json(post.into()))
}
}
}

View File

@ -1,13 +1,9 @@
use crate::{ use crate::{app::State, templates};
app::{Job, State},
templates,
};
use axum::{ use axum::{
body, body,
extract::Extension, extract::Extension,
http::StatusCode, http::StatusCode,
response::{Html, IntoResponse, Response}, response::{Html, IntoResponse, Response},
Json,
}; };
use chrono::{Datelike, Timelike, Utc, Weekday}; use chrono::{Datelike, Timelike, Utc, Weekday};
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -15,6 +11,7 @@ use prometheus::{opts, register_int_counter_vec, IntCounterVec};
use std::sync::Arc; use std::sync::Arc;
use tracing::instrument; use tracing::instrument;
pub mod api;
pub mod blog; pub mod blog;
pub mod feeds; pub mod feeds;
pub mod gallery; pub mod gallery;
@ -52,7 +49,7 @@ fn month_to_name(m: u32) -> &'static str {
} }
lazy_static! { lazy_static! {
static ref HIT_COUNTER: IntCounterVec = pub static ref HIT_COUNTER: IntCounterVec =
register_int_counter_vec!(opts!("hits", "Number of hits to various pages"), &["page"]) register_int_counter_vec!(opts!("hits", "Number of hits to various pages"), &["page"])
.unwrap(); .unwrap();
pub static ref LAST_MODIFIED: String = { pub static ref LAST_MODIFIED: String = {
@ -106,16 +103,6 @@ pub async fn salary_transparency(Extension(state): Extension<Arc<State>>) -> Res
Ok(Html(result)) Ok(Html(result))
} }
#[axum_macros::debug_handler]
#[instrument(skip(state))]
pub async fn salary_transparency_json(Extension(state): Extension<Arc<State>>) -> Json<Vec<Job>> {
HIT_COUNTER
.with_label_values(&["salary_transparency_json"])
.inc();
Json(state.clone().cfg.clone().job_history.clone())
}
#[axum_macros::debug_handler] #[axum_macros::debug_handler]
#[instrument(skip(state))] #[instrument(skip(state))]
pub async fn resume(Extension(state): Extension<Arc<State>>) -> Result { pub async fn resume(Extension(state): Extension<Arc<State>>) -> Result {

View File

@ -3,7 +3,6 @@ use crate::{app::State, post::Post, templates};
use axum::{ use axum::{
extract::{Extension, Path}, extract::{Extension, Path},
response::Html, response::Html,
Json,
}; };
use http::header::HeaderMap; use http::header::HeaderMap;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -17,11 +16,6 @@ lazy_static! {
&["name"] &["name"]
) )
.unwrap(); .unwrap();
static ref HIT_COUNTER_JSON: IntCounterVec = register_int_counter_vec!(
opts!("talks_json_hits", "Number of hits to talks images"),
&["name"]
)
.unwrap();
} }
#[instrument(skip(state))] #[instrument(skip(state))]
@ -67,28 +61,3 @@ pub async fn post_view(
} }
} }
} }
#[instrument(skip(state))]
pub async fn post_json(
Path(name): Path<String>,
Extension(state): Extension<Arc<State>>,
) -> Result<Json<xe_jsonfeed::Item>> {
let mut want: Option<Post> = None;
let want_link = format!("talks/{}", name);
for post in &state.talks {
if post.link == want_link {
want = Some(post.clone());
}
}
match want {
None => Err(super::Error::PostNotFound(name)),
Some(post) => {
HIT_COUNTER_JSON
.with_label_values(&[name.clone().as_str()])
.inc();
Ok(Json(post.into()))
}
}
}

View File

@ -156,12 +156,13 @@ async fn main() -> Result<()> {
), ),
) )
// api // api
.route("/api/new_post", get(handlers::feeds::new_post))
.route( .route(
"/api/salary_transparency.json", "/api/salary_transparency.json",
get(handlers::salary_transparency_json), get(handlers::api::salary_transparency),
) )
.route("/api/blog/:name", get(handlers::blog::post_json)) .route("/api/blog/:name", get(handlers::api::blog))
.route("/api/talks/:name", get(handlers::talks::post_json)) .route("/api/talks/:name", get(handlers::api::talk))
// static pages // static pages
.route("/", get(handlers::index)) .route("/", get(handlers::index))
.route("/contact", get(handlers::contact)) .route("/contact", get(handlers::contact))

View File

@ -1,6 +1,5 @@
@use super::{header_html, footer_html}; @use super::{header_html, footer_html};
@use crate::{post::Post, tmpl::nag}; @use crate::{post::Post, tmpl::nag};
@use chrono::prelude::*;
@(post: Post, body: impl ToHtml, referer: Option<String>) @(post: Post, body: impl ToHtml, referer: Option<String>)