Skip to content

Commit 5af0d96

Browse files
shashitnakMiaxos
authored andcommitted
adding support for dynamic schema
1 parent bcc1072 commit 5af0d96

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ tokio-comp = ["tokio"]
1818

1919
[dependencies]
2020
anyhow = "1"
21-
async-graphql = { version = "7" }
21+
async-graphql = { version = "7", features = ["dynamic-schema"] }
2222
async-trait = "0.1"
2323
chrono = "0.4"
2424
cfg-if = "1"

src/register.rs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! Implementation of the apollo Schema Reporting Protocol
44
//! <https://www.apollographql.com/docs/studio/schema/schema-reporting/>
5-
use async_graphql::{ObjectType, Schema, SubscriptionType};
5+
use async_graphql::{ObjectType, Schema, dynamic, SubscriptionType};
66
use reqwest::Client;
77
use sha2::{Digest, Sha256};
88
use uuid::Uuid;
@@ -27,6 +27,21 @@ pub fn sha<Q: ObjectType + 'static, M: ObjectType + 'static, S: SubscriptionType
2727
format!("{:x}", sha_from_schema)
2828
}
2929

30+
/**
31+
* Compute the SHA256 of a dynamic Schema
32+
* Usefull for Apollo Studio
33+
*/
34+
pub fn sha_dynamic(
35+
schema: &dynamic::Schema,
36+
) -> String {
37+
let mut hasher = Sha256::new();
38+
let schema_sdl = schema.sdl();
39+
let schema_bytes = schema_sdl.as_bytes();
40+
hasher.update(schema_bytes);
41+
let sha_from_schema = Sha256::digest(schema_bytes);
42+
format!("{:x}", sha_from_schema)
43+
}
44+
3045
/// Register your schema to Apollo Studio
3146
///
3247
/// * `authorization_token` - Token to send schema to apollo Studio.
@@ -128,3 +143,101 @@ pub async fn register<
128143
}
129144
}
130145
}
146+
147+
/// Register your dynamic schema to Apollo Studio
148+
///
149+
/// * `authorization_token` - Token to send schema to apollo Studio.
150+
/// * `schema` - async_graphql generated schema.
151+
/// * `server_id` - An ID that's unique for each instance of your edge server. Unlike bootId, this value should persist across an instance's restarts. In a Kubernetes cluster, this might be the pod name, whereas the container can restart.
152+
/// * `variant` - The name of the graph variant to register the schema to. The default value is current.
153+
/// * `user_version` - An arbitrary string you can set to distinguish data sent by different versions of your edge server. For example, this can be the SHA of the Git commit for your deployed server code. We plan to make this value visible in Apollo Studio.
154+
/// * `platform` - The infrastructure environment that your edge server is running in (localhost, kubernetes/deployment, aws lambda, google cloud run, google cloud function, AWS ECS, etc.)
155+
#[instrument(err, skip(authorization_token, schema))]
156+
pub async fn register_dynamic(
157+
authorization_token: &str,
158+
schema: &dynamic::Schema,
159+
server_id: &str,
160+
variant: &str,
161+
user_version: &str,
162+
platform: &str,
163+
) -> anyhow::Result<()> {
164+
info!(
165+
target: TARGET_LOG,
166+
message = "Apollo Studio - Register Schema"
167+
);
168+
let client = Client::new();
169+
let schema_sdl = schema.sdl();
170+
let sha_from_schema = sha_dynamic(schema);
171+
let boot_id = Uuid::new_v4();
172+
173+
let mutation = format!(
174+
r#"
175+
mutation($schema: String!) {{
176+
me {{
177+
... on ServiceMutation {{
178+
reportServerInfo(
179+
info: {{
180+
bootId: "{:?}"
181+
serverId: "{}"
182+
executableSchemaId: "{}"
183+
graphVariant: "{}"
184+
platform: "{}"
185+
libraryVersion: "async-studio-extension {}"
186+
runtimeVersion: "{}"
187+
userVersion: "{}"
188+
}}
189+
executableSchema: $schema
190+
) {{
191+
__typename
192+
... on ReportServerInfoError {{
193+
code
194+
message
195+
}}
196+
inSeconds
197+
withExecutableSchema
198+
}}
199+
}}
200+
}}
201+
}}
202+
"#,
203+
boot_id,
204+
server_id,
205+
sha_from_schema,
206+
variant,
207+
platform,
208+
VERSION,
209+
RUNTIME_VERSION,
210+
user_version
211+
);
212+
213+
let result = client
214+
.post(SCHEMA_URL)
215+
.json(&serde_json::json!({
216+
"query": mutation,
217+
"variables": {
218+
"schema": schema_sdl,
219+
},
220+
}))
221+
.header("content-type", "application/json")
222+
.header("X-Api-Key", authorization_token)
223+
.send()
224+
.await;
225+
226+
match result {
227+
Ok(data) => {
228+
info!(
229+
target: TARGET_LOG,
230+
message = "Schema correctly registered",
231+
response = &tracing::field::debug(&data)
232+
);
233+
let text = data.text().await;
234+
debug!(target: TARGET_LOG, data = ?text);
235+
Ok(())
236+
}
237+
Err(err) => {
238+
let status_code = err.status();
239+
error!(target: TARGET_LOG, status = ?status_code, error = ?err);
240+
Err(anyhow::anyhow!(err))
241+
}
242+
}
243+
}

0 commit comments

Comments
 (0)