From 9c5342a053e530113f7f2bb459c215c4863e8545 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Thu, 25 Nov 2021 12:35:47 +0530 Subject: [PATCH] light weight graphql query to fetch data to construct post URL --- schemas/query.graphql | 10 ++++++++++ schemas/schema.graphql | 1 + src/data.rs | 41 ++++++++++++++++++++++++++++++++++++++++- src/proxy.rs | 9 ++++----- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/schemas/query.graphql b/schemas/query.graphql index 6a1768f..3bc9943 100644 --- a/schemas/query.graphql +++ b/schemas/query.graphql @@ -8,6 +8,7 @@ query GetPost($id: ID!) { name id imageId + username } previewImage { id @@ -49,3 +50,12 @@ query GetPost($id: ID!) { } } } + +query GetPostLight($id: ID!) { + post(id: $id) { + uniqueSlug + creator { + username + } + } +} diff --git a/schemas/schema.graphql b/schemas/schema.graphql index ec6a74e..b0ec1ab 100644 --- a/schemas/schema.graphql +++ b/schemas/schema.graphql @@ -55,6 +55,7 @@ type User { id: String! name: String! imageId: String! + username: String! } type Post { diff --git a/src/data.rs b/src/data.rs index 2d49398..6be4bd3 100644 --- a/src/data.rs +++ b/src/data.rs @@ -26,7 +26,7 @@ use sled::{Db, Tree}; use crate::proxy::StringUtils; use crate::SETTINGS; -const POST_CACHE_VERSION: usize = 2; +const POST_CACHE_VERSION: usize = 3; const GIST_CACHE_VERSION: usize = 1; #[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 { pub fn new() -> AppData { 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::(&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) { match self.gists.get(&id) { Ok(Some(v)) => (id, bincode::deserialize(&v[..]).unwrap()), diff --git a/src/proxy.rs b/src/proxy.rs index 43c0d69..45a2d3c 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -151,14 +151,13 @@ async fn assets(path: web::Path, data: AppData) -> impl Responder { #[my_codegen::get(path = "crate::V1_API_ROUTES.proxy.by_post_id")] async fn by_post_id(path: web::Path, data: AppData) -> impl Responder { - let post_data = data.get_post(&path).await; - let author = format!("@{}", post_data.creator.username); + let post_data = data.get_post_light(&path).await; HttpResponse::Found() .append_header(( header::LOCATION, crate::V1_API_ROUTES .proxy - .get_page(&author, &post_data.unique_slug), + .get_page(&post_data.username, &post_data.slug), )) .finish() } @@ -260,8 +259,8 @@ mod tests { } let urls = vec![ - "/@ftrain/big-data-small-effort-b62607a43a8c", - "/@shawn-shi/rest-api-best-practices-decouple-long-running-tasks-from-http-request-processing-9fab2921ace8", + "/ftrain/big-data-small-effort-b62607a43a8c", + "/shawn-shi/rest-api-best-practices-decouple-long-running-tasks-from-http-request-processing-9fab2921ace8", ]; for uri in urls.iter() {