feat: implement full-text search functionality with API integration, add search router and persistence logic, and create related schemas and tests
This commit is contained in:
@@ -5,6 +5,7 @@ pub mod auth;
|
||||
pub mod feed;
|
||||
pub mod friends;
|
||||
pub mod root;
|
||||
pub mod search;
|
||||
pub mod tag;
|
||||
pub mod thought;
|
||||
pub mod user;
|
||||
@@ -30,6 +31,7 @@ pub fn create_router(state: AppState) -> Router {
|
||||
.nest("/feed", create_feed_router())
|
||||
.nest("/tags", tag::create_tag_router())
|
||||
.nest("/friends", friends::create_friends_router())
|
||||
.nest("/search", search::create_search_router())
|
||||
.with_state(state)
|
||||
.layer(cors)
|
||||
}
|
||||
|
53
thoughts-backend/api/src/routers/search.rs
Normal file
53
thoughts-backend/api/src/routers/search.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use crate::{error::ApiError, extractor::OptionalAuthUser};
|
||||
use app::{persistence::search, state::AppState};
|
||||
use axum::{
|
||||
extract::{Query, State},
|
||||
response::IntoResponse,
|
||||
routing::get,
|
||||
Json, Router,
|
||||
};
|
||||
use models::schemas::{
|
||||
search::SearchResultsSchema,
|
||||
thought::{ThoughtListSchema, ThoughtSchema},
|
||||
user::UserListSchema,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
#[derive(Deserialize, IntoParams)]
|
||||
pub struct SearchQuery {
|
||||
q: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "",
|
||||
params(SearchQuery),
|
||||
responses((status = 200, body = SearchResultsSchema))
|
||||
)]
|
||||
async fn search_all(
|
||||
State(state): State<AppState>,
|
||||
viewer: OptionalAuthUser,
|
||||
Query(query): Query<SearchQuery>,
|
||||
) -> Result<impl IntoResponse, ApiError> {
|
||||
let viewer_id = viewer.0.map(|u| u.id);
|
||||
|
||||
let (users, thoughts) = tokio::try_join!(
|
||||
search::search_users(&state.conn, &query.q),
|
||||
search::search_thoughts(&state.conn, &query.q, viewer_id)
|
||||
)?;
|
||||
|
||||
let thought_schemas: Vec<ThoughtSchema> =
|
||||
thoughts.into_iter().map(ThoughtSchema::from).collect();
|
||||
|
||||
let response = SearchResultsSchema {
|
||||
users: UserListSchema::from(users),
|
||||
thoughts: ThoughtListSchema::from(thought_schemas),
|
||||
};
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
pub fn create_search_router() -> Router<AppState> {
|
||||
Router::new().route("/", get(search_all))
|
||||
}
|
Reference in New Issue
Block a user