bsdkrun/graphql_transport

The HTTP half of the GraphQL transport used by bsdkrun/client: one POST per query or mutation, plus URL normalization. The WebSocket half (subscriptions) is bsdkrun/ws.

Mirrors web/src/lib/graphql.ts’s gql() and web/src/lib/connection.ts’s normalizeUrl — same request shape, same status/error interpretation, same URL rules, just over :httpc (bsdkrun_remote_ffi.erl’s http_post/3) instead of fetch.

parse_response — the status-code/body interpretation — is factored out from execute specifically so it can be unit-tested against literal (status, body) pairs with no socket involved (see test/client_test.gleam), per this feature’s own suggested fallback for testing the HTTP layer.

Values

pub fn execute(
  url: String,
  token: String,
  query: String,
  variables: json.Json,
) -> Result(dynamic.Dynamic, error.Error)

Run one GraphQL query or mutation against url (the full endpoint URL, e.g. http://host:50052/graphql) with token, and return its data field as a Dynamic for the caller to decode.

pub fn execute_raw(
  url: String,
  token: String,
  query: String,
  variables_json: String,
) -> Result(dynamic.Dynamic, error.Error)

Like execute, but takes variables as an already-serialized JSON string rather than a gleam_json-built Json value. Used by bsdkrun/client’s request/subscribe escape hatch, whose caller hands in a Dynamicbsdkrun_remote_ffi.erl’s dynamic_to_json/1 turns that into a JSON string directly, with nowhere for a Json value to come from in between.

pub fn normalize_url(input: String) -> String

Accept what a person actually types or pastes and turn it into the GraphQL endpoint URL: trim, add http:// when no scheme is given, strip trailing slashes, append /graphql unless the path already ends with it. Mirrors web/src/lib/connection.ts’s normalizeUrl exactly, including leaving an empty/blank input as "" rather than inventing an endpoint.

pub fn parse_response(
  status: Int,
  body: String,
) -> Result(dynamic.Dynamic, error.Error)

Interpret one HTTP response: a 401 is always an AuthError; otherwise the body is parsed as JSON and, if errors is a non-empty array, its first entry becomes an AuthError (when extensions.code is "UNAUTHENTICATED") or a GraphqlError (any other error). With no errors, the data field is returned as-is for the caller to decode.

Search Document