Discussing Shopify Functions development, deployment, and usage in Shopify apps.
Hello,
I am trying to build a Shopify function extension in Rust.
I wished to make an API request from inside my function. To do that, Shopify provides it's own way of handling requests.
I am following this article: https://shopify.dev/docs/apps/functions/input-output/network-access/using-network-access
src/fetch.rs
use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function_target(query_path = "src/fetch.graphql", schema_path = "schema.graphql")] fn fetch(input: fetch::input::ResponseData) -> Result<fetch::output::FunctionFetchResult> { let mut request: Option<output::HttpRequest> = None; // Network call if the buyer_identity is present if let Some(buyer_identity) = &input.cart.buyer_identity { // Network call if the email is present if let Some(_email) = &buyer_identity.email { let http_request = build_request(&input); request = Some(http_request); } } Ok(fetch::output::FunctionFetchResult { request }) } fn build_request(input: &fetch::input::ResponseData) -> fetch::output::HttpRequest { // Serializing the input for simple demonstration, the body can be articulated as needed. let body = serde_json::to_string(&input).expect("Error serializing"); static SERVER_URL: &'static str = "https://subdomain.example.com/some-endpoint"; fetch::output::HttpRequest { method: fetch::output::HttpRequestMethod::Other("POST".to_string()), url: SERVER_URL.to_string(), headers: [].to_vec(), body: Some(body), policy: fetch::output::HttpRequestPolicy { read_timeout_ms: 20000, }, } }
src/fetch.graphql
query Input { cart { buyerIdentity { email isAuthenticated } cost { totalAmount { amount currencyCode } } } }
src/run.rs
use shopify_function::prelude::*; use shopify_function::Result; use serde::Deserialize; #[derive(Deserialize)] struct ServerResponse { errors: Vec<ServerResponseError>, } #[derive(Deserialize)] struct ServerResponseError { localized_message: String, target: String, } #[shopify_function_target(query_path = "src/run.graphql", schema_path = "schema.graphql")] fn run(input: run::input::ResponseData) -> Result<run::output::FunctionRunResult> { // Optimization for when there are no requests. // In this simple example, there are no fallbacks, but there is room to implement one if needed. // See fetch.rs. if input.fetch_result.is_none() { return Ok(output::FunctionRunResult { errors: vec![] }); } let fetch_result = input.fetch_result.unwrap(); // When the server returns an unexpected response. // Optionally: Apply a local fallback error message. if fetch_result.status != 200 { panic!("Server response unprocessable (status)"); } let body = fetch_result.body.as_ref().expect("Missing response body"); match serde_json::from_str::<ServerResponse>(body.as_str()) { Ok(response) => { let errors: Vec<run::output::FunctionError> = response .errors .into_iter() .map(|error| run::output::FunctionError { localized_message: error.localized_message, target: error.target, }) .rev() .collect(); return Ok(run::output::FunctionRunResult { errors }); } Err(_) => { // Optionally: Apply a local fallback error message. panic!("Server response unprocessable (serialization)"); } } }
src/run.graphql
query Input { fetchResult { status headers { name value } body } }
I built and deployed this app to Shopify.
Then, I activated it from the test app's checkout settings.
I tested it by building a sample cart and going to checkout.
But, each time it gives the same thing in the logs:
To further narrow down the issue, I checked the logs on my API server. The server isn't receiving the HTTP request.
I am confused as to what is happening here.
All help would be appreciated.
Thank you.
This is an early access feature with limited availability, have you confirmed that it's been enabled for the shop in question?
Nick Wesselman | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog
Is it early access for every type of function ... why doesn't the first row say early access but the next 2 do. It would have saved me the entire day tracking it down. Shopify likes to give me a taste of hope then crush my dreams. When is this critical (I would almost say obvious basic necessary) feature going to be available for real big-boy enterprise apps. IT WOULD BE REALLY NICE TO HAVE BEFORE AUGUST WHEN YOU FORCE US TO REWRITE OUR CHECKOUT LIQUID PAGES........
and now Ive tried it on a developer preview store with same result. i feel like Im following the Shopify example here pretty closely.
Sorry, my answer was not complete -- in the case of cart validation, this is only available on the Shopify for enterprise plan. It is not enabled in any developer preview on Partners without a production shop on this plan.
Nick Wesselman | Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit the Shopify Help Center or the Shopify Blog