Skip to main content
Glama
manifest.rs3.35 kB
use std::collections::HashMap; use std::ops::Deref; use std::ops::DerefMut; use serde::Deserialize; use serde::Serialize; use tower::BoxError; /// The full identifier for an operation in a PQ list consists of an operation /// ID and an optional client name. #[derive(Debug, Clone, Eq, Hash, PartialEq)] pub struct FullPersistedQueryOperationId { /// The operation ID (usually a hash). pub operation_id: String, /// The client name associated with the operation; if None, can be any client. pub client_name: Option<String>, } /// A single operation containing an ID and a body. #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct ManifestOperation { /// The operation ID (usually a hash). pub id: String, /// The operation body. pub body: String, /// The client name associated with the operation. If None, can be any client. pub client_name: Option<String>, } /// The format of each persisted query chunk returned from uplink. #[derive(Debug, Clone, Deserialize, Serialize)] pub struct SignedUrlChunk { pub format: String, pub version: u64, pub operations: Vec<ManifestOperation>, } impl SignedUrlChunk { pub fn validate(self) -> Result<Self, BoxError> { if self.format != "apollo-persisted-query-manifest" { return Err("chunk format is not 'apollo-persisted-query-manifest'".into()); } if self.version != 1 { return Err("persisted query manifest chunk version is not 1".into()); } Ok(self) } pub fn parse_and_validate(raw_chunk: &str) -> Result<Self, BoxError> { let parsed_chunk = serde_json::from_str::<SignedUrlChunk>(raw_chunk).map_err(|e| -> BoxError { format!("Could not parse persisted query manifest chunk: {e}").into() })?; parsed_chunk.validate() } } /// An in memory cache of persisted queries. #[derive(Debug, Clone, Default)] pub struct PersistedQueryManifest { inner: HashMap<FullPersistedQueryOperationId, String>, } impl PersistedQueryManifest { /// Add a chunk to the manifest. pub fn add_chunk(&mut self, chunk: &SignedUrlChunk) { for operation in &chunk.operations { self.inner.insert( FullPersistedQueryOperationId { operation_id: operation.id.clone(), client_name: operation.client_name.clone(), }, operation.body.clone(), ); } } } impl From<Vec<ManifestOperation>> for PersistedQueryManifest { fn from(operations: Vec<ManifestOperation>) -> Self { let mut manifest = PersistedQueryManifest::default(); for operation in operations { manifest.insert( FullPersistedQueryOperationId { operation_id: operation.id, client_name: operation.client_name, }, operation.body, ); } manifest } } impl Deref for PersistedQueryManifest { type Target = HashMap<FullPersistedQueryOperationId, String>; fn deref(&self) -> &Self::Target { &self.inner } } impl DerefMut for PersistedQueryManifest { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } }

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/apollographql/apollo-mcp-server'

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