From 575ec2a06f72f273c3a7e2c3ff583328f9c99254 Mon Sep 17 00:00:00 2001 From: mpostma Date: Mon, 5 Jul 2021 14:29:20 +0200 Subject: [PATCH] refactor routes --- meilisearch-http/src/lib.rs | 11 +-- meilisearch-http/src/routes/dump.rs | 6 +- meilisearch-http/src/routes/health.rs | 11 --- .../{document.rs => indexes/documents.rs} | 29 +++--- .../src/routes/{index.rs => indexes/mod.rs} | 96 ++++++++----------- .../src/routes/{ => indexes}/search.rs | 4 +- .../src/routes/{ => indexes}/settings.rs | 35 +++---- .../src/routes/indexes/updates.rs | 64 +++++++++++++ meilisearch-http/src/routes/key.rs | 23 ----- meilisearch-http/src/routes/mod.rs | 75 +++++++++++++-- meilisearch-http/src/routes/stats.rs | 56 ----------- 11 files changed, 203 insertions(+), 207 deletions(-) delete mode 100644 meilisearch-http/src/routes/health.rs rename meilisearch-http/src/routes/{document.rs => indexes/documents.rs} (88%) rename meilisearch-http/src/routes/{index.rs => indexes/mod.rs} (64%) rename meilisearch-http/src/routes/{ => indexes}/search.rs (97%) rename meilisearch-http/src/routes/{ => indexes}/settings.rs (85%) create mode 100644 meilisearch-http/src/routes/indexes/updates.rs delete mode 100644 meilisearch-http/src/routes/key.rs delete mode 100644 meilisearch-http/src/routes/stats.rs diff --git a/meilisearch-http/src/lib.rs b/meilisearch-http/src/lib.rs index 0eb61f84c..bbc7cefab 100644 --- a/meilisearch-http/src/lib.rs +++ b/meilisearch-http/src/lib.rs @@ -106,20 +106,13 @@ macro_rules! create_app { use actix_web::middleware::TrailingSlash; use actix_web::App; use actix_web::{middleware, web}; - use meilisearch_http::routes::*; + use meilisearch_http::routes; use meilisearch_http::{configure_auth, configure_data, dashboard}; App::new() .configure(|s| configure_data(s, $data.clone())) .configure(|s| configure_auth(s, &$data)) - .configure(document::services) - .configure(index::services) - .configure(search::services) - .configure(settings::services) - .configure(health::services) - .configure(stats::services) - .configure(key::services) - .configure(dump::services) + .configure(routes::configure) .configure(|s| dashboard(s, $enable_frontend)) .wrap( Cors::default() diff --git a/meilisearch-http/src/routes/dump.rs b/meilisearch-http/src/routes/dump.rs index 1f987a588..18b143fa3 100644 --- a/meilisearch-http/src/routes/dump.rs +++ b/meilisearch-http/src/routes/dump.rs @@ -6,9 +6,9 @@ use crate::error::ResponseError; use crate::extractors::authentication::{policies::*, GuardedData}; use crate::Data; -pub fn services(cfg: &mut web::ServiceConfig) { - cfg.service(web::resource("/dumps").route(web::post().to(create_dump))) - .service(web::resource("/dumps/{dump_uid}/status").route(web::get().to(get_dump_status))); +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("").route(web::post().to(create_dump))) + .service(web::resource("/{dump_uid}/status").route(web::get().to(get_dump_status))); } async fn create_dump(data: GuardedData) -> Result { diff --git a/meilisearch-http/src/routes/health.rs b/meilisearch-http/src/routes/health.rs deleted file mode 100644 index 54237de1a..000000000 --- a/meilisearch-http/src/routes/health.rs +++ /dev/null @@ -1,11 +0,0 @@ -use actix_web::{web, HttpResponse}; - -use crate::error::ResponseError; - -pub fn services(cfg: &mut web::ServiceConfig) { - cfg.service(web::resource("/health").route(web::get().to(get_health))); -} - -async fn get_health() -> Result { - Ok(HttpResponse::Ok().json(serde_json::json!({ "status": "available" }))) -} diff --git a/meilisearch-http/src/routes/document.rs b/meilisearch-http/src/routes/indexes/documents.rs similarity index 88% rename from meilisearch-http/src/routes/document.rs rename to meilisearch-http/src/routes/indexes/documents.rs index 112467f67..a62a85f1b 100644 --- a/meilisearch-http/src/routes/document.rs +++ b/meilisearch-http/src/routes/indexes/documents.rs @@ -54,23 +54,20 @@ struct DocumentParam { document_id: String, } -pub fn services(cfg: &mut web::ServiceConfig) { +pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service( - web::scope("/indexes/{index_uid}/documents") - .service( - web::resource("") - .route(web::get().to(get_all_documents)) - .route(web::post().guard(guard_json).to(add_documents)) - .route(web::put().guard(guard_json).to(update_documents)) - .route(web::delete().to(clear_all_documents)), - ) - // this route needs to be before the /documents/{document_id} to match properly - .service(web::resource("/delete-batch").route(web::post().to(delete_documents))) - .service( - web::resource("/{document_id}") - .route(web::get().to(get_document)) - .route(web::delete().to(delete_document)), - ), + web::resource("") + .route(web::get().to(get_all_documents)) + .route(web::post().guard(guard_json).to(add_documents)) + .route(web::put().guard(guard_json).to(update_documents)) + .route(web::delete().to(clear_all_documents)), + ) + // this route needs to be before the /documents/{document_id} to match properly + .service(web::resource("/delete-batch").route(web::post().to(delete_documents))) + .service( + web::resource("/{document_id}") + .route(web::get().to(get_document)) + .route(web::delete().to(delete_document)), ); } diff --git a/meilisearch-http/src/routes/index.rs b/meilisearch-http/src/routes/indexes/mod.rs similarity index 64% rename from meilisearch-http/src/routes/index.rs rename to meilisearch-http/src/routes/indexes/mod.rs index badbdcc10..89fa366cb 100644 --- a/meilisearch-http/src/routes/index.rs +++ b/meilisearch-http/src/routes/indexes/mod.rs @@ -3,32 +3,44 @@ use chrono::{DateTime, Utc}; use log::debug; use serde::{Deserialize, Serialize}; -use super::{IndexParam, UpdateStatusResponse}; use crate::error::ResponseError; use crate::extractors::authentication::{policies::*, GuardedData}; +use crate::routes::IndexParam; use crate::Data; -pub fn services(cfg: &mut web::ServiceConfig) { +mod documents; +mod search; +mod settings; +mod updates; + +pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service( - web::resource("indexes") + web::resource("") .route(web::get().to(list_indexes)) .route(web::post().to(create_index)), ) .service( - web::resource("/indexes/{index_uid}") - .route(web::get().to(get_index)) - .route(web::put().to(update_index)) - .route(web::delete().to(delete_index)), - ) - .service( - web::resource("/indexes/{index_uid}/updates").route(web::get().to(get_all_updates_status)), - ) - .service( - web::resource("/indexes/{index_uid}/updates/{update_id}") - .route(web::get().to(get_update_status)), + web::scope("/{index_uid}") + .service( + web::resource("") + .route(web::get().to(get_index)) + .route(web::put().to(update_index)) + .route(web::delete().to(delete_index)), + ) + .service(web::resource("/stats").route(web::get().to(get_index_stats))) + .service(web::scope("/documents").configure(documents::configure)) + .service(web::scope("/search").configure(search::configure)) + .service(web::scope("/updates").configure(updates::configure)) + .service(web::scope("/settings").configure(settings::configure)), ); } +async fn list_indexes(data: GuardedData) -> Result { + let indexes = data.list_indexes().await?; + debug!("returns: {:?}", indexes); + Ok(HttpResponse::Ok().json(indexes)) +} + #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] struct IndexCreateRequest { @@ -36,6 +48,15 @@ struct IndexCreateRequest { primary_key: Option, } +async fn create_index( + data: GuardedData, + body: web::Json, +) -> Result { + let body = body.into_inner(); + let meta = data.create_index(body.uid, body.primary_key).await?; + Ok(HttpResponse::Ok().json(meta)) +} + #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] struct UpdateIndexRequest { @@ -52,22 +73,6 @@ pub struct UpdateIndexResponse { updated_at: DateTime, primary_key: Option, } - -async fn list_indexes(data: GuardedData) -> Result { - let indexes = data.list_indexes().await?; - debug!("returns: {:?}", indexes); - Ok(HttpResponse::Ok().json(indexes)) -} - -async fn create_index( - data: GuardedData, - body: web::Json, -) -> Result { - let body = body.into_inner(); - let meta = data.create_index(body.uid, body.primary_key).await?; - Ok(HttpResponse::Ok().json(meta)) -} - async fn get_index( data: GuardedData, path: web::Path, @@ -99,35 +104,12 @@ async fn delete_index( Ok(HttpResponse::NoContent().finish()) } -#[derive(Deserialize)] -struct UpdateParam { - index_uid: String, - update_id: u64, -} - -async fn get_update_status( - data: GuardedData, - path: web::Path, -) -> Result { - let params = path.into_inner(); - let meta = data - .get_update_status(params.index_uid, params.update_id) - .await?; - let meta = UpdateStatusResponse::from(meta); - debug!("returns: {:?}", meta); - Ok(HttpResponse::Ok().json(meta)) -} - -async fn get_all_updates_status( +async fn get_index_stats( data: GuardedData, path: web::Path, ) -> Result { - let metas = data.get_updates_status(path.into_inner().index_uid).await?; - let metas = metas - .into_iter() - .map(UpdateStatusResponse::from) - .collect::>(); + let response = data.get_index_stats(path.index_uid.clone()).await?; - debug!("returns: {:?}", metas); - Ok(HttpResponse::Ok().json(metas)) + debug!("returns: {:?}", response); + Ok(HttpResponse::Ok().json(response)) } diff --git a/meilisearch-http/src/routes/search.rs b/meilisearch-http/src/routes/indexes/search.rs similarity index 97% rename from meilisearch-http/src/routes/search.rs rename to meilisearch-http/src/routes/indexes/search.rs index 31a7dbd03..b6820018e 100644 --- a/meilisearch-http/src/routes/search.rs +++ b/meilisearch-http/src/routes/indexes/search.rs @@ -11,9 +11,9 @@ use crate::index::{default_crop_length, SearchQuery, DEFAULT_SEARCH_LIMIT}; use crate::routes::IndexParam; use crate::Data; -pub fn services(cfg: &mut web::ServiceConfig) { +pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service( - web::resource("/indexes/{index_uid}/search") + web::resource("") .route(web::get().to(search_with_url_query)) .route(web::post().to(search_with_post)), ); diff --git a/meilisearch-http/src/routes/settings.rs b/meilisearch-http/src/routes/indexes/settings.rs similarity index 85% rename from meilisearch-http/src/routes/settings.rs rename to meilisearch-http/src/routes/indexes/settings.rs index 812e37b58..272060bf5 100644 --- a/meilisearch-http/src/routes/settings.rs +++ b/meilisearch-http/src/routes/indexes/settings.rs @@ -69,68 +69,63 @@ macro_rules! make_setting_route { } make_setting_route!( - "/indexes/{index_uid}/settings/filterable-attributes", + "/filterable-attributes", std::collections::HashSet, filterable_attributes, "filterableAttributes" ); make_setting_route!( - "/indexes/{index_uid}/settings/displayed-attributes", + "/displayed-attributes", Vec, displayed_attributes, "displayedAttributes" ); make_setting_route!( - "/indexes/{index_uid}/settings/searchable-attributes", + "/searchable-attributes", Vec, searchable_attributes, "searchableAttributes" ); make_setting_route!( - "/indexes/{index_uid}/settings/stop-words", + "/stop-words", std::collections::BTreeSet, stop_words, "stopWords" ); make_setting_route!( - "/indexes/{index_uid}/settings/synonyms", + "/synonyms", std::collections::BTreeMap>, synonyms, "synonyms" ); make_setting_route!( - "/indexes/{index_uid}/settings/distinct-attribute", + "/distinct-attribute", String, distinct_attribute, "distinctAttribute" ); -make_setting_route!( - "/indexes/{index_uid}/settings/ranking-rules", - Vec, - ranking_rules, - "rankingRules" -); +make_setting_route!("/ranking-rules", Vec, ranking_rules, "rankingRules"); -macro_rules! create_services { +macro_rules! generate_configure { ($($mod:ident),*) => { - pub fn services(cfg: &mut web::ServiceConfig) { - cfg - .service(web::resource("/indexes/{index_uid}/settings") - .route(web::post().to(update_all)) - .route(web::get().to(get_all)) - .route(web::delete().to(delete_all))) + pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service( + web::resource("") + .route(web::post().to(update_all)) + .route(web::get().to(get_all)) + .route(web::delete().to(delete_all))) $(.service($mod::resources()))*; } }; } -create_services!( +generate_configure!( filterable_attributes, displayed_attributes, searchable_attributes, diff --git a/meilisearch-http/src/routes/indexes/updates.rs b/meilisearch-http/src/routes/indexes/updates.rs new file mode 100644 index 000000000..735736e97 --- /dev/null +++ b/meilisearch-http/src/routes/indexes/updates.rs @@ -0,0 +1,64 @@ +use actix_web::{web, HttpResponse}; +use chrono::{DateTime, Utc}; +use log::debug; +use serde::{Deserialize, Serialize}; + +use crate::error::ResponseError; +use crate::extractors::authentication::{policies::*, GuardedData}; +use crate::routes::{IndexParam, UpdateStatusResponse}; +use crate::Data; + +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("").route(web::get().to(get_all_updates_status))) + .service(web::resource("{update_id}").route(web::get().to(get_update_status))); +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct UpdateIndexRequest { + uid: Option, + primary_key: Option, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct UpdateIndexResponse { + name: String, + uid: String, + created_at: DateTime, + updated_at: DateTime, + primary_key: Option, +} + +#[derive(Deserialize)] +struct UpdateParam { + index_uid: String, + update_id: u64, +} + +async fn get_update_status( + data: GuardedData, + path: web::Path, +) -> Result { + let params = path.into_inner(); + let meta = data + .get_update_status(params.index_uid, params.update_id) + .await?; + let meta = UpdateStatusResponse::from(meta); + debug!("returns: {:?}", meta); + Ok(HttpResponse::Ok().json(meta)) +} + +async fn get_all_updates_status( + data: GuardedData, + path: web::Path, +) -> Result { + let metas = data.get_updates_status(path.into_inner().index_uid).await?; + let metas = metas + .into_iter() + .map(UpdateStatusResponse::from) + .collect::>(); + + debug!("returns: {:?}", metas); + Ok(HttpResponse::Ok().json(metas)) +} diff --git a/meilisearch-http/src/routes/key.rs b/meilisearch-http/src/routes/key.rs deleted file mode 100644 index d47e264be..000000000 --- a/meilisearch-http/src/routes/key.rs +++ /dev/null @@ -1,23 +0,0 @@ -use actix_web::{web, HttpResponse}; -use serde::Serialize; - -use crate::extractors::authentication::{policies::*, GuardedData}; -use crate::Data; - -pub fn services(cfg: &mut web::ServiceConfig) { - cfg.service(web::resource("/keys").route(web::get().to(list))); -} - -#[derive(Serialize)] -struct KeysResponse { - private: Option, - public: Option, -} - -async fn list(data: GuardedData) -> HttpResponse { - let api_keys = data.api_keys.clone(); - HttpResponse::Ok().json(&KeysResponse { - private: api_keys.private, - public: api_keys.public, - }) -} diff --git a/meilisearch-http/src/routes/mod.rs b/meilisearch-http/src/routes/mod.rs index 520949cd8..981d27e02 100644 --- a/meilisearch-http/src/routes/mod.rs +++ b/meilisearch-http/src/routes/mod.rs @@ -1,21 +1,27 @@ use std::time::Duration; -use actix_web::HttpResponse; +use actix_web::{web, HttpResponse}; use chrono::{DateTime, Utc}; +use log::debug; use serde::{Deserialize, Serialize}; use crate::error::ResponseError; +use crate::extractors::authentication::{policies::*, GuardedData}; use crate::index::{Settings, Unchecked}; use crate::index_controller::{UpdateMeta, UpdateResult, UpdateStatus}; +use crate::Data; -pub mod document; -pub mod dump; -pub mod health; -pub mod index; -pub mod key; -pub mod search; -pub mod settings; -pub mod stats; +mod dump; +mod indexes; + +pub fn configure(cfg: &mut web::ServiceConfig) { + cfg.service(web::resource("/health").route(web::get().to(get_health))) + .service(web::scope("/dumps").configure(dump::configure)) + .service(web::resource("/keys").route(web::get().to(list_keys))) + .service(web::resource("/stats").route(web::get().to(get_stats))) + .service(web::resource("/version").route(web::get().to(get_version))) + .service(web::scope("/indexes").configure(indexes::configure)); +} #[derive(Debug, Clone, Serialize, Deserialize)] #[allow(clippy::large_enum_variant)] @@ -43,7 +49,6 @@ pub enum UpdateType { impl From<&UpdateStatus> for UpdateType { fn from(other: &UpdateStatus) -> Self { use milli::update::IndexDocumentsMethod::*; - match other.meta() { UpdateMeta::DocumentsAddition { method, .. } => { let number = match other { @@ -223,3 +228,53 @@ impl IndexUpdateResponse { pub async fn running() -> HttpResponse { HttpResponse::Ok().json(serde_json::json!({ "status": "MeiliSearch is running" })) } + +async fn get_stats(data: GuardedData) -> Result { + let response = data.get_all_stats().await?; + + debug!("returns: {:?}", response); + Ok(HttpResponse::Ok().json(response)) +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct VersionResponse { + commit_sha: String, + commit_date: String, + pkg_version: String, +} + +async fn get_version(_data: GuardedData) -> HttpResponse { + let commit_sha = match option_env!("COMMIT_SHA") { + Some("") | None => env!("VERGEN_SHA"), + Some(commit_sha) => commit_sha, + }; + let commit_date = match option_env!("COMMIT_DATE") { + Some("") | None => env!("VERGEN_COMMIT_DATE"), + Some(commit_date) => commit_date, + }; + + HttpResponse::Ok().json(VersionResponse { + commit_sha: commit_sha.to_string(), + commit_date: commit_date.to_string(), + pkg_version: env!("CARGO_PKG_VERSION").to_string(), + }) +} + +#[derive(Serialize)] +struct KeysResponse { + private: Option, + public: Option, +} + +pub async fn list_keys(data: GuardedData) -> HttpResponse { + let api_keys = data.api_keys.clone(); + HttpResponse::Ok().json(&KeysResponse { + private: api_keys.private, + public: api_keys.public, + }) +} + +pub async fn get_health() -> Result { + Ok(HttpResponse::Ok().json(serde_json::json!({ "status": "available" }))) +} diff --git a/meilisearch-http/src/routes/stats.rs b/meilisearch-http/src/routes/stats.rs deleted file mode 100644 index a0078d76a..000000000 --- a/meilisearch-http/src/routes/stats.rs +++ /dev/null @@ -1,56 +0,0 @@ -use actix_web::{web, HttpResponse}; -use log::debug; -use serde::Serialize; - -use crate::error::ResponseError; -use crate::extractors::authentication::{policies::*, GuardedData}; -use crate::routes::IndexParam; -use crate::Data; - -pub fn services(cfg: &mut web::ServiceConfig) { - cfg.service(web::resource("/indexes/{index_uid}/stats").route(web::get().to(get_index_stats))) - .service(web::resource("/stats").route(web::get().to(get_stats))) - .service(web::resource("/version").route(web::get().to(get_version))); -} - -async fn get_index_stats( - data: GuardedData, - path: web::Path, -) -> Result { - let response = data.get_index_stats(path.index_uid.clone()).await?; - - debug!("returns: {:?}", response); - Ok(HttpResponse::Ok().json(response)) -} - -async fn get_stats(data: GuardedData) -> Result { - let response = data.get_all_stats().await?; - - debug!("returns: {:?}", response); - Ok(HttpResponse::Ok().json(response)) -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct VersionResponse { - commit_sha: String, - commit_date: String, - pkg_version: String, -} - -async fn get_version(_data: GuardedData) -> HttpResponse { - let commit_sha = match option_env!("COMMIT_SHA") { - Some("") | None => env!("VERGEN_SHA"), - Some(commit_sha) => commit_sha, - }; - let commit_date = match option_env!("COMMIT_DATE") { - Some("") | None => env!("VERGEN_COMMIT_DATE"), - Some(commit_date) => commit_date, - }; - - HttpResponse::Ok().json(VersionResponse { - commit_sha: commit_sha.to_string(), - commit_date: commit_date.to_string(), - pkg_version: env!("CARGO_PKG_VERSION").to_string(), - }) -}