Skip to main content

StorefrontClient

Struct StorefrontClient 

Source
pub struct StorefrontClient { /* private fields */ }
Expand description

GraphQL client for Shopify Storefront API.

Provides methods (query, query_with_debug) for executing GraphQL queries against the Storefront API with support for public tokens, private tokens, and tokenless access.

§Thread Safety

StorefrontClient is Send + Sync, making it safe to share across async tasks.

§Endpoint Format

The Storefront API uses a different endpoint format than the Admin API:

  • Storefront: https://{shop}/api/{version}/graphql.json
  • Admin: https://{shop}/admin/api/{version}/graphql.json

§Authentication

The client supports three authentication modes:

  • Public token: Uses X-Shopify-Storefront-Access-Token header
  • Private token: Uses Shopify-Storefront-Private-Token header
  • Tokenless: No authentication header (limited access)

§Example

use shopify_sdk::{StorefrontClient, StorefrontToken, ShopDomain};
use serde_json::json;

let shop = ShopDomain::new("my-store").unwrap();

// Public token access
let token = StorefrontToken::Public("public-access-token".to_string());
let client = StorefrontClient::new(&shop, Some(token), None);

// Tokenless access for basic features
let client = StorefrontClient::new(&shop, None, None);

// Query with variables
let response = client.query(
    "query GetProducts($first: Int!) { products(first: $first) { edges { node { title } } } }",
    Some(json!({ "first": 10 })),
    None,
    None
).await?;

// Check for GraphQL errors (HTTP 200 with errors in body)
if let Some(errors) = response.body.get("errors") {
    println!("GraphQL errors: {}", errors);
}

Implementations§

Source§

impl StorefrontClient

Source

pub fn new( shop: &ShopDomain, token: Option<StorefrontToken>, config: Option<&ShopifyConfig>, ) -> Self

Creates a new Storefront client for the given shop.

This constructor uses the API version from the configuration, or falls back to the latest stable version if not specified.

Unlike GraphqlClient, this constructor takes a ShopDomain directly instead of a Session, since Storefront API uses storefront tokens rather than admin tokens.

§Arguments
  • shop - The shop domain for endpoint construction
  • token - Optional storefront access token (None for tokenless access)
  • config - Optional configuration for API version and other settings
§Example
use shopify_sdk::{StorefrontClient, StorefrontToken, ShopDomain};

let shop = ShopDomain::new("my-store").unwrap();

// With public token
let token = StorefrontToken::Public("my-token".to_string());
let client = StorefrontClient::new(&shop, Some(token), None);

// Tokenless access
let client = StorefrontClient::new(&shop, None, None);
Source

pub fn with_version( shop: &ShopDomain, token: Option<StorefrontToken>, config: Option<&ShopifyConfig>, version: ApiVersion, ) -> Self

Creates a new Storefront client with a specific API version override.

This constructor allows overriding the API version from configuration.

§Arguments
  • shop - The shop domain for endpoint construction
  • token - Optional storefront access token (None for tokenless access)
  • config - Optional configuration for other settings
  • version - The API version to use for requests
§Example
use shopify_sdk::{StorefrontClient, StorefrontToken, ShopDomain, ApiVersion};

let shop = ShopDomain::new("my-store").unwrap();
let token = StorefrontToken::Public("my-token".to_string());

// Use a specific API version
let client = StorefrontClient::with_version(&shop, Some(token), None, ApiVersion::V2024_10);
assert_eq!(client.api_version(), &ApiVersion::V2024_10);
Source

pub const fn api_version(&self) -> &ApiVersion

Returns the API version being used by this client.

Source

pub async fn query( &self, query: &str, variables: Option<Value>, headers: Option<HashMap<String, String>>, tries: Option<u32>, ) -> Result<HttpResponse, GraphqlError>

Executes a GraphQL query against the Storefront API.

This method sends a POST request to the graphql.json endpoint with the query and optional variables.

§Arguments
  • query - The GraphQL query string
  • variables - Optional variables for the query
  • headers - Optional extra headers to include in the request
  • tries - Optional number of retry attempts (default: 1, no retries)
§Returns

Returns the raw HttpResponse containing:

  • code: HTTP status code (usually 200 for GraphQL)
  • headers: Response headers
  • body: JSON response with data, errors, and extensions fields
§Errors

Returns GraphqlError::Http for HTTP-level errors (network errors, non-2xx responses, retry exhaustion).

Note that GraphQL-level errors (user errors, validation errors) are returned with HTTP 200 status and contained in response.body["errors"].

§Example
use shopify_sdk::StorefrontClient;
use serde_json::json;

// Simple query
let response = client.query(
    "query { shop { name } }",
    None,
    None,
    None
).await?;

println!("Shop: {}", response.body["data"]["shop"]["name"]);

// Query with variables and retries
let response = client.query(
    "query GetProduct($handle: String!) { productByHandle(handle: $handle) { title } }",
    Some(json!({ "handle": "my-product" })),
    None,
    Some(3) // Retry up to 3 times on 429/500
).await?;

// Check for GraphQL errors
if let Some(errors) = response.body.get("errors") {
    println!("GraphQL errors: {}", errors);
}
Source

pub async fn query_with_debug( &self, query: &str, variables: Option<Value>, headers: Option<HashMap<String, String>>, tries: Option<u32>, ) -> Result<HttpResponse, GraphqlError>

Executes a GraphQL query with debug mode enabled.

This method is identical to query but appends ?debug=true to the request URL, which causes Shopify to include additional query cost and execution information in the response’s extensions field.

§Arguments
  • query - The GraphQL query string
  • variables - Optional variables for the query
  • headers - Optional extra headers to include in the request
  • tries - Optional number of retry attempts (default: 1, no retries)
§Returns

Returns the raw HttpResponse with additional debug information in response.body["extensions"].

§Errors

Returns GraphqlError::Http for HTTP-level errors.

§Example
use shopify_sdk::StorefrontClient;

let response = client.query_with_debug(
    "query { products(first: 10) { edges { node { title } } } }",
    None,
    None,
    None
).await?;

// Debug info available in extensions
if let Some(extensions) = response.body.get("extensions") {
    println!("Query cost: {}", extensions["cost"]);
}

Trait Implementations§

Source§

impl Debug for StorefrontClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more