light weight graphql query to fetch data to construct post URL

This commit is contained in:
Aravinth Manivannan 2021-11-25 12:35:47 +05:30
parent 32934c8353
commit 9c5342a053
Signed by untrusted user: realaravinth
GPG key ID: AD9F0F08E855ED88
4 changed files with 55 additions and 6 deletions

View file

@ -8,6 +8,7 @@ query GetPost($id: ID!) {
name name
id id
imageId imageId
username
} }
previewImage { previewImage {
id id
@ -49,3 +50,12 @@ query GetPost($id: ID!) {
} }
} }
} }
query GetPostLight($id: ID!) {
post(id: $id) {
uniqueSlug
creator {
username
}
}
}

View file

@ -55,6 +55,7 @@ type User {
id: String! id: String!
name: String! name: String!
imageId: String! imageId: String!
username: String!
} }
type Post { type Post {

View file

@ -26,7 +26,7 @@ use sled::{Db, Tree};
use crate::proxy::StringUtils; use crate::proxy::StringUtils;
use crate::SETTINGS; use crate::SETTINGS;
const POST_CACHE_VERSION: usize = 2; const POST_CACHE_VERSION: usize = 3;
const GIST_CACHE_VERSION: usize = 1; const GIST_CACHE_VERSION: usize = 1;
#[derive(Clone)] #[derive(Clone)]
@ -87,6 +87,20 @@ impl GistFile {
} }
} }
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schemas/schema.graphql",
query_path = "schemas/query.graphql",
response_derives = "Debug, Serialize, Deserialize, Clone"
)]
pub struct GetPostLight;
#[derive(Debug, Clone)]
pub struct PostUrl {
pub slug: String,
pub username: String,
}
impl Data { impl Data {
pub fn new() -> AppData { pub fn new() -> AppData {
let path = Path::new(SETTINGS.cache.as_ref().unwrap()).join("posts_cache"); let path = Path::new(SETTINGS.cache.as_ref().unwrap()).join("posts_cache");
@ -152,6 +166,31 @@ impl Data {
} }
} }
pub async fn get_post_light(&self, id: &str) -> PostUrl {
match self.posts.get(id) {
Ok(Some(v)) => {
let cached: PostResp = bincode::deserialize(&v[..]).unwrap();
PostUrl {
slug: cached.unique_slug,
username: cached.creator.username,
}
}
_ => {
let vars = get_post_light::Variables { id: id.to_owned() };
const URL: &str = "https://medium.com/_/graphql";
let res = post_graphql::<GetPostLight, _>(&self.client, URL, vars)
.await
.unwrap();
let res = res.data.expect("missing response data").post.unwrap();
PostUrl {
slug: res.unique_slug,
username: res.creator.username,
}
}
}
}
pub async fn get_gist(&self, id: String) -> (String, GistContent) { pub async fn get_gist(&self, id: String) -> (String, GistContent) {
match self.gists.get(&id) { match self.gists.get(&id) {
Ok(Some(v)) => (id, bincode::deserialize(&v[..]).unwrap()), Ok(Some(v)) => (id, bincode::deserialize(&v[..]).unwrap()),

View file

@ -151,14 +151,13 @@ async fn assets(path: web::Path<String>, data: AppData) -> impl Responder {
#[my_codegen::get(path = "crate::V1_API_ROUTES.proxy.by_post_id")] #[my_codegen::get(path = "crate::V1_API_ROUTES.proxy.by_post_id")]
async fn by_post_id(path: web::Path<String>, data: AppData) -> impl Responder { async fn by_post_id(path: web::Path<String>, data: AppData) -> impl Responder {
let post_data = data.get_post(&path).await; let post_data = data.get_post_light(&path).await;
let author = format!("@{}", post_data.creator.username);
HttpResponse::Found() HttpResponse::Found()
.append_header(( .append_header((
header::LOCATION, header::LOCATION,
crate::V1_API_ROUTES crate::V1_API_ROUTES
.proxy .proxy
.get_page(&author, &post_data.unique_slug), .get_page(&post_data.username, &post_data.slug),
)) ))
.finish() .finish()
} }
@ -260,8 +259,8 @@ mod tests {
} }
let urls = vec![ let urls = vec![
"/@ftrain/big-data-small-effort-b62607a43a8c", "/ftrain/big-data-small-effort-b62607a43a8c",
"/@shawn-shi/rest-api-best-practices-decouple-long-running-tasks-from-http-request-processing-9fab2921ace8", "/shawn-shi/rest-api-best-practices-decouple-long-running-tasks-from-http-request-processing-9fab2921ace8",
]; ];
for uri in urls.iter() { for uri in urls.iter() {