Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support sha256 and md5 algos for local file persister #3878

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 102 additions & 20 deletions compiler/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler/crates/relay-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ serde = { version = "1.0.136", features = ["derive", "rc"] }
serde_bser = "0.3"
serde_json = { version = "1.0.79", features = ["float_roundtrip", "unbounded_depth"] }
sha-1 = "0.8"
sha256 = "1.0.3"
signedsource = { path = "../signedsource" }
thiserror = "1.0.30"
tokio = { version = "1.15", features = ["full", "test-util", "tracing"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

use async_trait::async_trait;
use dashmap::DashMap;
use md5::Md5;
use persist_query::PersistError;
use relay_config::LocalPersistConfig;
use relay_config::{LocalPersistAlgorithm, LocalPersistConfig};
use sha1::{Digest, Sha1};
use std::collections::BTreeMap;

Expand All @@ -35,9 +36,19 @@ impl LocalPersister {
}

fn hash_operation(&self, operation_text: String) -> String {
let mut hash = Sha1::new();
hash.input(&operation_text);
hex::encode(hash.result())
match self.config.algorithm {
LocalPersistAlgorithm::MD5 => {
let mut md5 = Md5::new();
md5.input(operation_text);
hex::encode(md5.result())
}
LocalPersistAlgorithm::SHA1 => {
let mut hash = Sha1::new();
hash.input(&operation_text);
hex::encode(hash.result())
}
LocalPersistAlgorithm::SHA256 => sha256::digest(operation_text),
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/crates/relay-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod typegen_config;
pub use connection_interface::ConnectionInterface;
pub use js_module_format::JsModuleFormat;
pub use project_config::{
LocalPersistConfig, PersistConfig, ProjectConfig, ProjectName, RemotePersistConfig,
SchemaConfig, SchemaLocation,
LocalPersistAlgorithm, LocalPersistConfig, PersistConfig, ProjectConfig, ProjectName,
RemotePersistConfig, SchemaConfig, SchemaLocation,
};
pub use typegen_config::{FlowTypegenConfig, TypegenConfig, TypegenLanguage};
17 changes: 17 additions & 0 deletions compiler/crates/relay-config/src/project_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,27 @@ where
Ok(Some(permits))
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum LocalPersistAlgorithm {
MD5,
SHA1,
SHA256,
}

impl Default for LocalPersistAlgorithm {
// For backwards compatibility
fn default() -> Self {
Self::MD5
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LocalPersistConfig {
pub file: PathBuf,

#[serde(default)]
pub algorithm: LocalPersistAlgorithm,
}

#[derive(Debug, Serialize, Clone)]
Expand Down
26 changes: 26 additions & 0 deletions website/docs/guides/persisted-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,32 @@ You can also add additional request body parameters via the `params` option.
}
```

### Local Persisted Queries

With the following config, you can generate a local JSON file which contains a map of `operation_id => full operation text`.

```
"scripts": {
"relay": "relay-compiler"
},
"relay": {
"src": "./src",
"schema": "./schema.graphql",
"persistConfig": {
"file": "./persisted_queries.json",
"algorithm": "MD5" // this can be one of MD5, SHA256, SHA1
}
}
```

Ideally, you'll take this file and ship it to your server at deploy time so your server knows about all the queries it could possibly receive. If you don't want to do that, you'll have to implement the [Automatic Persisted Queries handshake](https://www.apollographql.com/docs/apollo-server/performance/apq/).

#### Tradeoffs

- ✅ If your server's persisted query datastore gets wiped, you can recover automatically through your client's requests.
- ❌ When there's a cache miss, it'll cost you an extra round trip to the server.
- ❌ You'll have to ship your `persisted_queries.json` file to the browser which will increase your bundle size.

### Example implemetation of `relayLocalPersisting.js`

Here's an example of a simple persist server that will save query text to the `queryMap.json` file.
Expand Down