Auto-indexing service and GraphQL API for AT Protocol Records quickslice.slices.network/
atproto gleam graphql
at main 65 lines 1.6 kB view raw
1import database/executor.{type Executor} 2import gleam/erlang/process.{type Subject} 3import gleam/json 4import gleam/option.{type Option} 5import gleam/result 6import graphql/lexicon/schema as lexicon_schema 7import lib/oauth/did_cache 8 9/// Execute a GraphQL query 10pub fn execute_query( 11 db: Executor, 12 query: String, 13 variables_json: String, 14 did_cache: Subject(did_cache.Message), 15 signing_key: Option(String), 16 plc_url: String, 17) -> Result(json.Json, String) { 18 use result_str <- result.try(lexicon_schema.execute_query_with_db( 19 db, 20 query, 21 variables_json, 22 Error(Nil), 23 // No auth token for MCP queries 24 did_cache, 25 signing_key, 26 "", 27 // Empty atp_client_id - MCP queries don't do mutations that need ATP refresh 28 plc_url, 29 )) 30 31 // Return the result string wrapped in a JSON object 32 Ok(json.object([#("result", json.string(result_str))])) 33} 34 35/// Get full GraphQL schema introspection 36pub fn introspect_schema( 37 db: Executor, 38 did_cache: Subject(did_cache.Message), 39 signing_key: Option(String), 40 plc_url: String, 41) -> Result(json.Json, String) { 42 let introspection_query = 43 " 44 query IntrospectionQuery { 45 __schema { 46 queryType { name } 47 mutationType { name } 48 subscriptionType { name } 49 types { 50 name 51 kind 52 description 53 fields { 54 name 55 description 56 args { name type { name } } 57 type { name kind ofType { name kind } } 58 } 59 } 60 } 61 } 62 " 63 64 execute_query(db, introspection_query, "{}", did_cache, signing_key, plc_url) 65}