Skip to main content
Glama
get_module_details_route.rs2.82 kB
use axum::{ Json, extract::{ Path, Query, }, response::{ IntoResponse, Response, }, }; use hyper::StatusCode; use module_index_types::ModuleDetailsResponse; use sea_orm::{ ColumnTrait, DatabaseTransaction, DbErr, EntityTrait, QueryFilter, }; use serde::{ Deserialize, Serialize, }; use serde_json::{ Value, json, }; use thiserror::Error; use crate::{ extract::{ Authorization, DbConnection, }, models::si_module::{ self, ModuleId, SchemaIdReferenceLink, make_module_details_response, }, }; #[remain::sorted] #[derive(Error, Debug)] pub enum GetModuleDetailsError { #[error("db error: {0}")] DbErr(#[from] DbErr), #[error(r#"More than one matching module found for id: "{0}""#)] MoreThanOneMatchingModuleFor(ModuleId), #[error(r#"Module "{0}" not found"#)] NotFound(ModuleId), } // TODO: figure out how to not keep this serialization logic here impl IntoResponse for GetModuleDetailsError { fn into_response(self) -> Response { let (status, error_message) = match self { Self::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()), _ => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), }; let body = Json( serde_json::json!({ "error": { "message": error_message, "code": 42, "statusCode": status.as_u16() } }), ); (status, body).into_response() } } #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] pub struct GetModuleDetailsRequest { pub foo: Option<bool>, } pub async fn get_module_details_route( Path(module_id): Path<ModuleId>, Authorization { .. }: Authorization, DbConnection(txn): DbConnection, Query(_request): Query<GetModuleDetailsRequest>, ) -> Result<Json<Value>, GetModuleDetailsError> { let module = get_module_by_id_opt(module_id, &txn) .await? .ok_or(GetModuleDetailsError::NotFound(module_id))?; Ok(Json(json!(module))) } pub async fn get_module_by_id_opt( module_id: ModuleId, txn: &DatabaseTransaction, ) -> Result<Option<ModuleDetailsResponse>, GetModuleDetailsError> { let query = si_module::Entity::find() .find_with_linked(SchemaIdReferenceLink) .filter(si_module::Column::Id.eq(module_id)); let modules: Vec<ModuleDetailsResponse> = query .all(txn) .await? .into_iter() .map(|(module, linked_modules)| make_module_details_response(module, linked_modules)) .collect(); if modules.len() > 1 { return Err(GetModuleDetailsError::MoreThanOneMatchingModuleFor( module_id, )); } let module = modules.first().cloned(); Ok(module) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server