### Install Gem Dependencies Source: https://github.com/shopify/shopify-api-ruby/blob/main/README.md Install all project dependencies using Bundler after cloning the repository. ```bash bundle install ``` -------------------------------- ### Initialize ShopifyAPI::Context Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md Call ShopifyAPI::Context.setup when your app starts to configure global settings. This holds configurations for your app and defines library behavior. ```ruby ShopifyAPI::Context.setup( api_key: "", api_secret_key: "", host_name: "", scope: "read_orders,read_products,etc", is_embedded: true, # Set to true if you are building an embedded app is_private: false, # Set to true if you are building a private app api_version: "2021-01" # The version of the API you would like to use user_agent_prefix: "" # Set a custom prefix for "User-Agent" header when making API requests ### ) ``` -------------------------------- ### Install Shopify API Gem Source: https://github.com/shopify/shopify-api-ruby/blob/main/README.md Add the shopify_api gem to your Gemfile to include it in your project. ```ruby gem "shopify_api" ``` -------------------------------- ### Create Product using REST Admin Client Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md This snippet shows how to create a new product using the REST Admin Client. It involves initializing the client, defining the product data in a hash, and using the `put` method to send the request to the appropriate API endpoint. Note that this example uses `put` for demonstration, but `post` would typically be used for creation. ```ruby # Create a new client. rest_client = ShopifyAPI::Clients::Rest::Admin.new # Update product title body = { product: { title: "My cool product" } } # Use `client.put` to send your request to the specified Shopify Admin REST API endpoint. rest_client.put(path: "products/.json", body: body) ``` -------------------------------- ### Initialize Storefront API Client and Query Data Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/graphql_storefront.md Initializes the Storefront API client with a shop URL and a private access token, then executes a GraphQL query to fetch collections and their products. Includes an example of an alternative initialization with a public access token and a note about the `Shopify-Storefront-Buyer-IP` header. ```ruby storefront_private_access_token = '' shop_url = 'shop.myshopify.com' client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, private_token: storefront_private_access_token) # or, alternatively with a public Storefront access token: # client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, public_token: storefront_public_access_token) query = <<~QUERY { collections(first: 2) { edges { node { id products(first: 5) { edges { node { id title } } } } } } } QUERY response = client.query(query: query, headers: { "Shopify-Storefront-Buyer-IP": request.remote_ip }) ``` -------------------------------- ### Get Products with Limit Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Fetches a specified number of products from the store. Uses the :limit parameter. ```ruby ShopifyAPI::Product.find(:all, :params => {:limit => 10}) ``` -------------------------------- ### Initialize Shopify API Context Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/getting_started.md Set up the Shopify API context with your application's parameters. This should be called when your app starts. Ensure all parameters are correctly configured for your app type (embedded/private) and desired API version. ```ruby ShopifyAPI::Context.setup( api_key: "", api_secret_key: "", host_name: "", scope: "read_orders,read_products,etc", is_embedded: true, # Set to true if you are building an embedded app is_private: false, # Set to true if you are building a private app api_version: "2021-01", # The version of the API you would like to use expiring_offline_access_tokens: true # Set to true to enable expiring offline access tokens with refresh tokens ) ``` -------------------------------- ### Get Metafields for First Product Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Retrieves all metafields associated with the first product found in the store. ```ruby ShopifyAPI::Product.first.metafields ``` -------------------------------- ### Get All Application Charges Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Retrieves a list of all application charges associated with the shop. ```ruby ShopifyAPI::ApplicationCharge.all ``` -------------------------------- ### Enable Expiring Tokens in Context Setup Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/oauth.md Configure the Shopify API context to request and receive expiring tokens for new installations. This is a crucial step when migrating to a token expiration strategy. ```ruby ShopifyAPI::Context.setup( expiring_offline_access_tokens: true, # ... other config ) ``` -------------------------------- ### Add Shopify API Gem with Bundler Source: https://github.com/shopify/shopify-api-ruby/blob/main/README.md Use the bundle add command to install the shopify_api gem if you are using Bundler. ```bash bundle add shopify_api ``` -------------------------------- ### Instantiate Orders Object with Hash Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md This example shows how to create a new Orders object using a hash of properties. It utilizes the default session, which is automatically inferred if no explicit session is provided. The `save!` method is then called to persist the order. ```ruby # To construct an Orders object using default session # This creates a new order object with properties provided from the hash order = ShopifyAPI::Orders.new(from_hash: {property: value}) order.save! ``` -------------------------------- ### Get Current Shop Information Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Retrieves information about the currently authenticated shop. ```ruby ShopifyAPI::Shop.current ``` -------------------------------- ### GraphQL Client Query (v9) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md Example of how to make a GraphQL query using the older ShopifyAPI::GraphQL client before v10. The API version was set on ShopifyAPI::Base.api_version. ```ruby ShopifyAPI::Base.api_version = "2023-04" client = ShopifyAPI::GraphQL.client SHOP_NAME_QUERY = client.parse <<-'GRAPHQL' { shop { name } } GRAPHQL result = client.query(SHOP_NAME_QUERY) shop_name = result.data.shop.name ``` -------------------------------- ### Get All Orders Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Retrieves a list of all orders associated with the shop. ```APIDOC ## GET /admin/api/2023-10/orders.json ### Description Retrieves a list of all orders. ### Method GET ### Endpoint `/admin/api/2023-10/orders.json` ### Parameters #### Query Parameters - **status** (string) - Optional - Filter orders by their status (e.g., 'open', 'closed', 'cancelled'). - **limit** (integer) - Optional - The number of results to return per page. - **since_id** (integer) - Optional - Retrieve orders created after the specified ID. ### Response #### Success Response (200) - **orders** (array) - An array of order objects. #### Response Example ```json { "orders": [ { "id": 1001, "order_number": "#1001", "email": "customer@example.com", "total_price": "50.00", "created_at": "2023-10-27T13:00:00Z" }, { "id": 1002, "order_number": "#1002", "email": "another@example.com", "total_price": "75.00", "created_at": "2023-10-27T13:05:00Z" } ] } ``` ``` -------------------------------- ### Get All Orders Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Retrieve a list of all orders using the `all` method. ```Ruby # Get all orders orders = ShopifyAPI::Orders.all ``` -------------------------------- ### Perform a GET Request to Products Endpoint Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Use `client.get` to fetch a list of products from the Shopify REST API. Ensure you have a valid session and have created a `ShopifyAPI::Clients::Rest::Admin` client instance. ```ruby # Create a new client. client = ShopifyAPI::Clients::Rest::Admin.new(session: session) # Use `client.get` to request the specified Shopify REST API endpoint, in this case `products`. response = client.get(path: "products") # Do something with the returned data some_function(response.body) ``` -------------------------------- ### Configure Shopify API Context for OAuth Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/oauth.md Configure the Shopify API client with your application's credentials and the required access scopes. This setup is necessary before initiating the OAuth flow. ```ruby ShopifyAPI::Context.setup( api_key: , api_secret_key: , api_version: , scope: , # Accepts array or string: "read_orders, write_products" or ["read_orders", "write_products"] ... ) ``` -------------------------------- ### Get Orders by Creation Date Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Fetches orders, sorted by creation date in descending order, with a specified limit. ```ruby ShopifyAPI::Order.find(:all, :params => {:limit => 5, :order => "created_at DESC" }) ``` -------------------------------- ### Checkout and Pull Main Branch Source: https://github.com/shopify/shopify-api-ruby/blob/main/RELEASING.md Ensures the local main branch is up-to-date with the remote repository before starting the release process. ```bash git checkout main git pull origin main ``` -------------------------------- ### Get First Metafield Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Retrieves the very first metafield record available in the shop. ```ruby ShopifyAPI::Metafield.first ``` -------------------------------- ### Define Route to Start OAuth Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/oauth.md Add a route in your Rails controller to initiate the OAuth process when a user navigates to a specific URL. ```ruby class ShopifyAuthController < ApplicationController def login # This method will trigger the start of the OAuth process end end ``` -------------------------------- ### Accessing Rate Limit Information Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Retrieve request count, bucket size, and retry after information from the Resource class to manage API rate limits. This information is available on the `Product` resource in this example. ```ruby product = ShopifyAPI::Product.find(session: session, id: 12345) # X-Shopify-Shop-Api-Call-Limit: 32/40 request_count = ShopifyAPI::Product.api_call_limit[:request_count] # 32 bucket_size = ShopifyAPI::Product.api_call_limit[:bucket_size] # 40 retry_after = ShopifyAPI::Product.retry_request_after ``` -------------------------------- ### Webhook Handler Implementation Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/webhooks.md Implement a module or class that includes ShopifyAPI::Webhooks::WebhookHandler and defines a handle method to process incoming webhook data. This example logs received data and enqueues background work. ```ruby module WebhookHandler extend ShopifyAPI::Webhooks::WebhookHandler class << self def handle(data:) puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version}" perform_later(topic: data.topic, shop_domain: data.shop, webhook: data.body) end end end ``` -------------------------------- ### Update Context API Version in Tests Source: https://github.com/shopify/shopify-api-ruby/blob/main/REST_RESOURCES.md In the `setup` method of your test files, update the `api_version` parameter in `ShopifyAPI::Context.activate_session` to reflect the new API version. ```ruby def setup super test_session = ShopifyAPI::Auth::Session.new(id: "id", shop: "test-shop.myshopify.io", access_token: "this_is_a_test_token") ShopifyAPI::Context.activate_session(test_session) # Update this line: modify_context(api_version: "2025-07") # Was "2025-04" end ``` -------------------------------- ### Process an HTTP Webhook Request in Rails Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/webhooks.md This example shows how to process an incoming HTTP webhook request within a Rails controller. It constructs a ShopifyAPI::Webhooks::Request object and uses the Registry to process it, verifying the request and calling the appropriate handler. ```ruby class WebhookController < ApplicationController def webhook ShopifyAPI::Webhooks::Registry.process( ShopifyAPI::Webhooks::Request.new(raw_body: request.raw_post, headers: request.headers.to_h) ) render json: {success: true}.to_json end end ``` -------------------------------- ### ShopifyAPI::Clients::Rest::Admin Instantiation Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Demonstrates how to create an instance of the REST Admin client, with options for specifying session and API version. ```APIDOC ## Class: ShopifyAPI::Clients::Rest::Admin ### Description Provides methods to interact with the Shopify Admin REST API. ### Instantiation Create an instance of `ShopifyAPI::Clients::Rest::Admin` to make requests. ### Constructor Parameters #### `session` - **Type**: `ShopifyAPI::Auth::Session` - **Notes**: If `nil`, the active session is inferred from `ShopifyAPI::Context.active_session`. Set active session using `ShopifyAPI::Context.activate_session`. #### `api_version` - **Type**: `String` - **Notes**: If `nil`, the API version is inferred from `ShopifyAPI::Context.setup`. ### Examples ```ruby # Create a default client using active session and default API version client = ShopifyAPI::Clients::Rest::Admin.new # Create a client with a specific session client = ShopifyAPI::Clients::Rest::Admin.new(session: my_session) # Create a client with a specific API version client = ShopifyAPI::Clients::Rest::Admin.new(api_version: "unstable") # Create a client with both a specific session and API version client = ShopifyAPI::Clients::Rest::Admin.new(session: my_session, api_version: "unstable") ``` ``` -------------------------------- ### Get Session ID from Shopify ID Token (Embedded) Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/getting_started.md A specialized method to get the session ID directly from a Shopify ID token for embedded apps. The `id_token` should not be prefixed with 'Bearer '. ```ruby ShopifyAPI::Utils::SessionUtils::session_id_from_shopify_id_token(id_token: id_token, online: true) ``` ```ruby ShopifyAPI::Utils::SessionUtils::session_id_from_shopify_id_token(id_token: id_token, online: false) ``` -------------------------------- ### Create a Product using POST Request Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Use `client.post` to send a POST request to the `products` endpoint to create a new product. Ensure the request body is correctly formatted. ```ruby body = { product: { title: "Burton Custom Freestyle 151", body_html: "\u003cstrong\u003eGood snowboard!\u003c\/strong\u003e", vendor: "Burton", product_type: "Snowboard", } } client.post({ path: "products", body: body, }); ``` -------------------------------- ### API Version Constant Removal: Context.setup Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This illustrates the migration for `ShopifyAPI::Context.setup` where the `api_version` parameter must now be explicitly set to a version string, as the old constants are removed. ```ruby # Before (v14 and earlier) ShopifyAPI::Context.setup( api_key: "", api_secret_key: "", host: "", scope: "read_orders,read_products,etc", is_embedded: true, api_version: ShopifyAPI::LATEST_SUPPORTED_ADMIN_VERSION, # This constant no longer exists is_private: false, ) # After (v15+) ShopifyAPI::Context.setup( api_key: "", api_secret_key: "", host: "", scope: "read_orders,read_products,etc", is_embedded: true, api_version: "2025-07", # Explicitly specify the version is_private: false, ) ``` -------------------------------- ### Initialize Storefront API Client with Unstable API Version Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/graphql_storefront.md Demonstrates how to initialize the Storefront API client to use the 'unstable' API version, which is useful for experimenting with prerelease API features. ```ruby client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, private_token: storefront_private_access_token, api_version: "unstable" ) ``` -------------------------------- ### Instantiate GraphQL Admin Client Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/graphql.md Create an instance of the GraphQL Admin client with a session and optional API version. If the session or API version is nil, it will attempt to infer them from the ShopifyAPI::Context. ```ruby client = ShopifyAPI::Clients::Graphql::Admin.new(session: session, api_version: "unstable") ``` -------------------------------- ### Create New Product from Hash Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md This snippet demonstrates creating a new product by initializing it with a hash containing the product's properties. The `save!` method is then called to create the product on Shopify. ```ruby # Create a new product from hash product_properties = { title: "My awesome product" } product = ShopifyAPI::Product.new(from_hash: product_properties) product.save! ``` -------------------------------- ### Get All Recurring Charges Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Retrieves a list of all recurring charges, whether active, canceled, or pending. ```ruby ShopifyAPI::RecurringApplicationCharge.all ``` -------------------------------- ### Instantiate REST Admin Client (Default) Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Create a default instance of the REST Admin client using the active session and API version from ShopifyAPI::Context. ```Ruby # Create a default client with `ShopifyAPI::Context.api_version` # and the active session from `ShopifyAPI::Context.active_session` client = ShopifyAPI::Clients::Rest::Admin.new ``` -------------------------------- ### Copy Resource and Test Files Source: https://github.com/shopify/shopify-api-ruby/blob/main/REST_RESOURCES.md Copy all resource files from the previous version's directory to the new version's directory. Similarly, copy all test files from the previous version's test directory to the new version's test directory. ```bash # Copy resource files cp -r lib/shopify_api/rest/resources/{PREVIOUS_VERSION}/* lib/shopify_api/rest/resources/{NEW_VERSION}/ # Copy test files cp -r test/rest/{PREVIOUS_VERSION}/* test/rest/{NEW_VERSION}/ ``` ```bash cp -r lib/shopify_api/rest/resources/2025_04/* lib/shopify_api/rest/resources/2025_07/ cp -r test/rest/2025_04/* test/rest/2025_07/ ``` -------------------------------- ### Run RuboCop Linter Source: https://github.com/shopify/shopify-api-ruby/blob/main/README.md Check code style and formatting using RuboCop. ```bash bundle exec rubocop ``` -------------------------------- ### Create Test Directory Source: https://github.com/shopify/shopify-api-ruby/blob/main/REST_RESOURCES.md Create a new directory for the test files of the new API version. The directory name should follow the `YYYY_MM` format. ```bash mkdir test/rest/{YYYY_MM}/ ``` -------------------------------- ### Initialize a Session Object Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/custom_apps.md Construct a basic Session object for custom apps. Ensure your shop name and access token are correctly provided. ```ruby session = ShopifyAPI::Auth::Session.new( shop: "#{your_shop_name}.myshopify.com", access_token: "the_token_for_your_custom_app_found_in_admin" ) ``` -------------------------------- ### Make a Basic GraphQL Query Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/graphql.md Perform a basic GraphQL query using the initialized client. The query string is defined using a heredoc. The response body contains the data, and pagination information is available if applicable. ```ruby # Initialize the client client = ShopifyAPI::Clients::Graphql::Admin.new(session: session) # Make the GraphQL query string query =<<~QUERY { products(first: 10) { edges { cursor node { id title onlineStoreUrl } } } } QUERY response = client.query(query: query) # do something with the response data product = response.body["data"]["products"]["edges"][0] my_function(product) ``` -------------------------------- ### Get Session ID from Non-Embedded App Cookies Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/getting_started.md Retrieve the session ID for non-embedded applications using cookies. Use the appropriate method for online (user) or offline (store) sessions. ```ruby ShopifyAPI::Utils::SessionUtils.current_session_id(nil, cookies, true) ``` ```ruby ShopifyAPI::Utils::SessionUtils.current_session_id(nil, cookies, false) ``` -------------------------------- ### Storefront GraphQL Client: Named Token Parameters (Required) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This demonstrates the new required implementation for initializing the Storefront GraphQL client using named parameters for private or public tokens. This is the recommended approach. ```ruby # Use private token (recommended) client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, private_token: storefront_private_access_token) # Or use public token client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, public_token: storefront_public_access_token) # With API version client = ShopifyAPI::Clients::Graphql::Storefront.new( shop_url, private_token: storefront_private_access_token, api_version: "2024-01" ) ``` -------------------------------- ### Get Session ID from Embedded App Request Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/getting_started.md Extract the session ID for embedded applications using the `shopify_id_token` from the HTTP authorization header or URL parameters. Supports both online and offline sessions. ```ruby ShopifyAPI::Utils::SessionUtils.current_session_id(shopify_id_token, nil, true) ``` ```ruby ShopifyAPI::Utils::SessionUtils.current_session_id(shopify_id_token, nil, false) ``` -------------------------------- ### Webhook Handling with WebhookHandler Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This demonstrates the new implementation for handling webhooks using `ShopifyAPI::Webhooks::WebhookHandler`. It shows how to include the module and implement the `handle` method with named parameters for flexibility. ```ruby module WebhookHandler extend ShopifyAPI::Webhooks::WebhookHandler class << self def handle(data:) puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version}" end end end ``` -------------------------------- ### Create Resource Directory Source: https://github.com/shopify/shopify-api-ruby/blob/main/REST_RESOURCES.md Create a new directory for the resource files of the new API version. The directory name should follow the `YYYY_MM` format. ```bash mkdir lib/shopify_api/rest/resources/{YYYY_MM}/ ``` -------------------------------- ### Commit and Push Release Preparation Source: https://github.com/shopify/shopify-api-ruby/blob/main/RELEASING.md Stages all changes, commits them with a release preparation message, and pushes the release branch to the remote repository. ```bash git add -A git commit -m "preparing for release v X.Y.Z" git push origin release-X.Y.Z ``` -------------------------------- ### Define OAuth Callback Route Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/oauth.md Set up a route to handle the callback from Shopify after the user has granted permissions. This route is specified in the `begin_auth` method. ```ruby class ShopifyCallbackController < ApplicationController def callback # This callback method will be called once user grants permission to this app from Shopify Admin. end end ``` -------------------------------- ### Create New Product Manually Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md This snippet shows how to create a new product by manually assigning its properties after initializing an empty product object. The `save!` method is then called to create the product on Shopify. ```ruby # Create a new product manually product = ShopifyAPI::Product.new product.title = "Another one" product.save! ``` -------------------------------- ### Create and Push Git Tag Source: https://github.com/shopify/shopify-api-ruby/blob/main/RELEASING.md Creates a local tag for the release version, forces it if it already exists, and then pushes the tag to the remote repository. ```bash git tag -f vX.Y.Z && git push origin vX.Y.Z ``` -------------------------------- ### Create a Webhook Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Creates a webhook to receive notifications for specific events. Requires topic, format, and address. ```ruby ShopifyAPI::Webhook.create(:topic => "app/uninstalled", :format => "json", :address => "http://your-url.com/uninstall") ``` -------------------------------- ### Instantiate REST Admin Client with Specific Session and API Version Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Create a REST Admin client instance with both a specific session object and a specific API version. ```Ruby # Create a client with a specific session "my_session" and api_version "unstable" client = ShopifyAPI::Clients::Rest::Admin.new(session: my_session, api_version: "unstable") ``` -------------------------------- ### Instantiate REST Admin Client with Specific API Version Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Create a REST Admin client instance using the active session and a specific API version. ```Ruby # Create a client with active session from `ShopifyAPI::Context.active_session` # and a specific api_version - "unstable" client = ShopifyAPI::Clients::Rest::Admin.new(api_version: "unstable") ``` -------------------------------- ### Configure Response as Struct Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/graphql.md Pass `response_as_struct: true` to `ShopifyAPI::Context.setup` to receive GraphQL responses as structs. This allows access to data using both dot and hash notation. ```ruby ShopifyAPI::Context.setup( api_key: ShopifyApp.configuration.api_key, api_secret_key: ShopifyApp.configuration.secret, ... response_as_struct: true ) ``` -------------------------------- ### Shopify App Gem Session Storage Implementation Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V16.md This code shows the reference implementation for session storage provided by the `shopify_app` gem. It demonstrates how to store individual session attributes and reconstruct sessions using `Session.new()`. ```ruby # Stores attributes in database columns def store(auth_session) shop = find_or_initialize_by(shopify_domain: auth_session.shop) shop.shopify_token = auth_session.access_token shop.save! end # Reconstructs using Session.new() def retrieve(id) shop = find_by(id: id) return unless shop ShopifyAPI::Auth::Session.new( shop: shop.shopify_domain, access_token: shop.shopify_token ) end ``` -------------------------------- ### Update ShopifyAPI::Session Initialization Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md When creating sessions, `api_version` is now a required keyword argument. Update the initialization of `ShopifyAPI::Session` and `ShopifyAPI::Session.temp` to use keyword arguments for all parameters. ```ruby ShopifyAPI::Session.new(domain: domain, token: token, api_version: api_version, extras: extras) ``` ```ruby ShopifyAPI::Session.temp(domain: domain, token: token, api_version: api_version) do ... end ``` ```ruby session = ShopifyAPI::Session.new(domain: domain, token: token, api_version: '2019-04') ``` ```ruby session = ShopifyAPI::Session.new(domain: domain, token: token, api_version: :unstable) ``` -------------------------------- ### Instantiate API Clients with Session Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md Manually specify a session when instantiating API clients. If the session is nil, it defaults to the active session from ShopifyAPI::Context.active_session. ```ruby # Manually specifying a session (ShopifyAPI::Auth::Session) in API clients. # GraphQL Client graphql_client = ShopifyAPI::Clients::Graphql::Admin.new(session: session) # REST Client rest_client = ShopifyAPI::Clients::Rest::Admin.new(session: session) # Using REST Resources rest_resource = ShopifyAPI::Shop.new(session: session) ``` -------------------------------- ### Configure and Activate Session for Global Use Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/custom_apps.md Set up Shopify API context and activate a session to be used automatically by all API clients. This is useful for embedded or private apps where a single session is maintained. ```ruby #### Configuration def configure_app # This method is called before making authenticated API calls session = ShopifyAPI::Auth::Session.new( shop: "#{your_shop_name}.myshopify.com", access_token: "the_token_for_your_custom_app_found_in_admin" ) ShopifyAPI::Context.setup( api_key: "", api_secret_key: "", scope: "read_orders,read_products,etc", is_embedded: true, # Set to true if you are building an embedded app api_version: "2024-01", # The version of the API you would like to use is_private: true, # Set to true if you have an existing private app ) # Activate session to be used in all API calls # session must be type `ShopifyAPI::Auth::Session` ShopifyAPI::Context.activate_session(session) end #### Using clients to make authenticated API calls def make_api_request # 1. Create API client without session information # The graphql_client will use `ShopifyAPI::Context.active_session` when making API calls # you can set the api version for your GraphQL client to override the api version in ShopifyAPI::Context graphql_client = ShopifyAPI::Clients::Graphql::Admin.new(api_version: "2024-07") # 2. Use API client to make queries # Graphql query = <<~QUERY { products(first: 10) { edges { cursor node { id title onlineStoreUrl } } } } QUERY response = graphql_client.query(query: query) # Use REST resources to make authenticated API call product_count = ShopifyAPI::Product.count ... end ``` -------------------------------- ### Storefront GraphQL Client: Positional Token (Deprecated) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This shows the previous implementation for initializing the Storefront GraphQL client, where the access token was passed as a positional parameter. This method is deprecated. ```ruby client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, storefront_access_token) # With API version client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, storefront_access_token, api_version: "2024-01") ``` -------------------------------- ### Execute Test Suite Source: https://github.com/shopify/shopify-api-ruby/blob/main/REST_RESOURCES.md Run the test suite to ensure all changes are correctly implemented and no regressions have been introduced. You can run all tests or filter by a specific version's test directory. ```bash # Run all tests bundle exec rake test # Run specific version tests bundle exec rake test TEST=test/rest/{NEW_VERSION}/* ``` -------------------------------- ### Instantiate REST Admin Client with Specific Session Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Create a REST Admin client instance with a specific session object. ```Ruby # Create a client with a specific session "my_session" client = ShopifyAPI::Clients::Rest::Admin.new(session: my_session) ``` -------------------------------- ### Create a One-Time Application Charge Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Creates a one-time charge for a specific action. Requires name, price, and return_url. ```ruby ShopifyAPI::ApplicationCharge.create({:name => "Super Duper Expensive action", :price => 100.0, :return_url => "http://super-duper.shopifyapps.com"}) ``` -------------------------------- ### Register All Webhooks for a Shop Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/webhooks.md Use this method to register all topics added to the registry for a specific shop. It returns an array of registration results. ```ruby ShopifyAPI::Webhooks::Registry.register_all(session: shop_session) ``` -------------------------------- ### Make a REST API Call using Admin Client Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md Use the `ShopifyAPI::Clients::Rest::Admin` client to make HTTP requests. Use `client.put` for updating resources like products. ```ruby # Create a new client. client = ShopifyAPI::Clients::Rest::Admin.new(session: session) # Update title for product with ID body = { product: { title: "My cool product" } } # Use `client.put` to send your request to the specified Shopify Admin REST API endpoint. client.put(path: "products/.json", body: body) ``` -------------------------------- ### ShopifyAPI::Clients::Rest::Admin Methods Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Overview of the core HTTP request methods available on the REST Admin client. ```APIDOC ## Class: ShopifyAPI::Clients::Rest::Admin ### Description Offers core HTTP request methods for interacting with the Admin API. ### Methods - **`get(path:, params: {})`**: Performs an HTTP GET request. - **`delete(path:, params: {})`**: Performs an HTTP DELETE request. - **`post(path:, payload: {})`**: Performs an HTTP POST request. - **`put(path:, payload: {})`**: Performs an HTTP PUT request. ### Parameters - **`path`** (String): The API endpoint path (e.g., `/orders.json`). - **`params`** (Hash): Query parameters for GET and DELETE requests. - **`payload`** (Hash): The request body for POST and PUT requests. ``` -------------------------------- ### REST Resource Pagination Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Implement cursor-based pagination using REST Resources. Use `ShopifyAPI::Product.next_page?` and `ShopifyAPI::Product.next_page_info` to iterate through paginated results. ```ruby products = ShopifyAPI::Product.all(session: session, limit: 10) loop do some_function(products) break unless ShopifyAPI::Product.next_page? products = ShopifyAPI::Product.all(session: session, limit: 10, page_info: ShopifyAPI::Product.next_page_info) end ``` -------------------------------- ### Initiate Shopify OAuth Authentication Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/oauth.md Use `ShopifyAPI::Auth::Oauth.begin_auth` to generate an authorization URL and a session cookie. This method is called when a user needs to grant your app permissions. ```ruby class ShopifyAuthController < ApplicationController def login shop = request.headers["Shop"] # Builds the authorization URL route to redirect the user to auth_response = ShopifyAPI::Auth::Oauth.begin_auth(shop: domain, redirect_path: "/auth/callback") # Store the authorization cookie cookies[auth_response[:cookie].name] = { expires: auth_response[:cookie].expires, secure: true, http_only: true, value: auth_response[:cookie].value } # Redirect the user to "auth_response[:auth_route]" to allow user to grant the app permission # This will lead the user to the Shopify Authorization page head 307 response.set_header("Location", auth_response[:auth_route]) end end ``` -------------------------------- ### Update Product Title Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Find a product by its ID and update its title, then save the changes. ```Ruby product = ShopifyAPI::Product.find(id: product_id) product.title = "My new title" product.save! ``` -------------------------------- ### REST API Client Methods Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md This section outlines the parameters and output for interacting with the REST Admin API via the Ruby client. It covers input parameters like path, body, query, and extraHeaders, as well as the structure of success and failure responses. ```APIDOC ## REST API Client Operations ### Description This documentation describes how to use the `ShopifyAPI::Clients::Rest::Admin` client to perform operations against the Shopify REST Admin API. It details the available parameters for requests and the structure of responses, including error handling. ### Parameters Each method can take the following parameters: - **`path`** (String) - Required - The requested API endpoint path. Can be a path relative to `/admin/api/{version}/` (e.g., `products`) or a full path (e.g., `/admin/oauth/access_scopes.json`). - **`body`** (Hash) - Required for `put`, `post` methods - The body of the request. - **`query`** (Hash) - Optional - A query object to be appended to the request URL as a query string. - **`extraHeaders`** (Hash) - Optional - Any additional headers to send with the request. - **`tries`** (Integer) - Optional - The maximum number of times to try the request (defaults to 1, must be >= 0). ### Output #### Success Response Upon successful request, methods return a `ShopifyAPI::Clients::HttpResponse` object with the following attributes: - **`code`** (Integer) - The HTTP Response code (e.g., `200`). - **`headers`** (Hash{String, [String]}) - HTTP Response headers. - **`body`** (Hash{String, Untyped}) - The HTTP Response body. - **`prev_page_info`** (String) - Information for the previous page of results (see [Pagination](#pagination)). - **`next_page_info`** (String) - Information for the next page of results (see [Pagination](#pagination)). #### Failure Response If the request fails, an error will be raised. You can rescue `ShopifyAPI::Errors::HttpResponseError` to handle these errors. ```ruby client = ShopifyAPI::Clients::Rest::Admin.new(session: session) response = client.get(path: "NOT-REAL") some_function(response.body) rescue ShopifyAPI::Errors::HttpResponseError => e puts e.errors.full_messages end ``` ### Usage Examples #### Perform a `GET` request ```ruby # Create a new client. client = ShopifyAPI::Clients::Rest::Admin.new(session: session) # Use `client.get` to request the specified Shopify REST API endpoint. response = client.get(path: "products") # Do something with the returned data some_function(response.body) ``` #### Perform a `POST` request ```ruby # Create a new client. client = ShopifyAPI::Clients::Rest::Admin.new(session: session) # Use `client.post` to send data to the specified Shopify REST API endpoint. # Example for creating a product (details omitted for brevity). # response = client.post(path: "products", body: { product: { title: "Awesome T-Shirt", ... } }) ``` ``` -------------------------------- ### Create a ScriptTag Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Creates a new ScriptTag to include a JavaScript file on the storefront. Requires src and event parameters. ```ruby ShopifyAPI::ScriptTag.create({:src => "http://your-url.com/script.js", :event => 'onload'}) ``` -------------------------------- ### API Version Constant Removal: Direct Usage Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This shows how to migrate from using the removed `LATEST_SUPPORTED_ADMIN_VERSION` or `RELEASE_CANDIDATE_ADMIN_VERSION` constants to explicitly specifying the desired API version string. ```ruby # Before (v14 and earlier) api_version = ShopifyAPI::LATEST_SUPPORTED_ADMIN_VERSION # or api_version = ShopifyAPI::RELEASE_CANDIDATE_ADMIN_VERSION # After (v15+) api_version = "2025-07" # Explicitly specify the version you want to use ``` -------------------------------- ### Create a Recurring Subscription Charge Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Creates a new recurring subscription charge for a plan. Requires name, price, and optionally trial_days. ```ruby ShopifyAPI::RecurringApplicationCharge.create({:name => "Basic Plan", :price => 15.0, :trial_days => 7}) ``` -------------------------------- ### Refactor GraphQL Client Query (v10+) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md Use the new ShopifyAPI::Clients::Graphql::Admin for GraphQL queries in v10+. The API version is specified during client initialization. Session must be an instance of ShopifyAPI::Auth::Session. ```ruby client = ShopifyAPI::Clients::Graphql::Admin.new(session: session, api_version: "2023-04") # session must be an instance of ShopifyAPI::Auth::Session, see Section - [2. Session Changes] SHOP_NAME_QUERY =<<~QUERY { shop { name } } QUERY response = client.query(query: query) shop_name = response.body["data"]["shop"]["name"] ``` -------------------------------- ### Previous Session Serialization (Removed in v16.0.0) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V16.md This code demonstrates the previous implementation of session serialization and deserialization using `Session#serialize` and `Session.deserialize`. These methods are no longer available in v16.0.0. ```ruby session = ShopifyAPI::Auth::Session.new( shop: "example.myshopify.com", access_token: "shpat_xxxxx", scope: "read_products,write_orders" ) serialized_data = session.serialize # Store serialized_data in Redis, database, etc. redis.set("session:#{session.id}", serialized_data) # Retrieving a session serialized_data = redis.get("session:#{session_id}") session = ShopifyAPI::Auth::Session.deserialize(serialized_data) ``` -------------------------------- ### REST Admin Client Pagination Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Implement cursor-based pagination using the REST Admin Client. Fetch the next page of results by passing `next_page_info` as a query parameter in subsequent requests. ```ruby client = ShopifyAPI::Clients::Rest::Admin.new(session: session) response = client.get(path: "products", query: { limit: 10 }) next_page_info = response.next_page_info if next_page_info next_page_response =client.get(path: "products", query: { limit: 10, page_info: next_page_info }) some_function(next_page_response) end ``` -------------------------------- ### Format CHANGELOG Entry Source: https://github.com/shopify/shopify-api-ruby/blob/main/RELEASING.md Provides the markdown format for adding a new release entry to the CHANGELOG file, including PR number and description. ```markdown ## X.Y.Z (YYYY-MM-DD) - [#PR_NUMBER](https://github.com/Shopify/shopify-api-ruby/pull/PR_NUMBER) Description of change ``` -------------------------------- ### Find Partially Paid Orders (Order Resource) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md Use `Order.all` instead of `Order.find(:all)` for finding orders with specific financial statuses. ```ruby Order.find(:all, params: {financial_status: "partially_paid"}) ``` ```ruby Order.all(financial_status: "partially_paid") ``` -------------------------------- ### Create Release Branch Source: https://github.com/shopify/shopify-api-ruby/blob/main/RELEASING.md Creates a new branch for the upcoming release, following a versioned naming convention. ```bash git checkout -b vX.Y.Z ``` -------------------------------- ### Find Order by ID (Order Resource) Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V10.md When finding an order by ID, use `Order.find(id: )` instead of `Order.find().` ```ruby Order.find() ``` ```ruby Order.find(id: ) ``` -------------------------------- ### Previous Webhook Handler Implementation Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This snippet shows the previous implementation of the WebhookHandler module. It includes a simple handle method for processing incoming webhooks. ```ruby module WebhookHandler include ShopifyAPI::Webhooks::Handler class << self def handle(topic:, shop:, body:) puts "Received webhook! topic: #{topic} shop: #{shop} body: #{body}" end end end ``` -------------------------------- ### Set API Version Lookup Mode to Raise on Unknown Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md Configure the API version lookup to raise an error for unknown versions. This ensures that only known and active versions are used. Known versions are fetched from Shopify and cached. ```ruby ShopifyAPI::ApiVersion.version_lookup_mode = :raise_on_unknown ShopifyAPI::ApiVersion.fetch_known_versions ``` -------------------------------- ### Update Product Title Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/rest.md Find an existing product by its ID, modify its title, and save the changes to the API. ```APIDOC ## PUT /admin/api/2023-10/products/{product_id}.json ### Description Updates an existing product's attributes. ### Method PUT ### Endpoint `/admin/api/2023-10/products/{product_id}.json` ### Parameters #### Path Parameters - **product_id** (integer) - Required - The unique identifier of the product to update. #### Request Body - **title** (string) - Optional - The new title for the product. ### Request Example ```json { "product": { "id": 12345, "title": "My new title" } } ``` ### Response #### Success Response (200) - **product** (object) - The updated product object. #### Response Example ```json { "product": { "id": 12345, "title": "My new title", "body_html": "

Description

", "vendor": "Vendor Name", "product_type": "Type", "created_at": "2023-10-27T10:00:00Z", "updated_at": "2023-10-27T10:05:00Z" } } ``` ``` -------------------------------- ### Make API Calls by Passing Session Object Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/custom_apps.md Create an API client and make requests by explicitly passing the session object. This method is suitable for scenarios where you manage sessions per request. ```ruby def make_api_request(shop) # 1. create session object session = ShopifyAPI::Auth::Session.new( shop: "#{your_shop_name}.myshopify.com", access_token: "the_token_for_your_custom_app_found_in_admin" ) # 2a. Create API client with the session information # session must be type `ShopifyAPI::Auth::Session` graphql_client = ShopifyAPI::Clients::Graphql::Admin.new(session: session) response = graphql_client.query(query: MY_API_QUERY) # 2b. REST example product_count = ShopifyAPI::Product.count(session: session) ... end ``` -------------------------------- ### Update Resource Prefix Definition Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md The `self.prefix` method for defining resource prefixes in classes extending `ShopifyAPI::Base` is deprecated. Use `self.resource_prefix` instead and do not include `/admin`. ```ruby class MyResource < ShopifyAPI::Base self.resource_prefix = 'shop/' end ``` -------------------------------- ### Register Specific Webhook Topic for a Shop Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/webhooks.md Use this method to register a single, specific topic for a shop. It returns a single registration result. ```ruby ShopifyAPI::Webhooks::Registry.register(topic: "", session: shop_session) ``` -------------------------------- ### Supported Admin Versions Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_V15.md This code snippet shows how to retrieve a list of all supported Shopify Admin API versions, which can be used to determine the correct version string to specify. ```ruby ShopifyAPI::SUPPORTED_ADMIN_VERSIONS # => ["unstable", "2025-10", "2025-07", "2025-04", ...] ``` -------------------------------- ### Update URL Construction for API Calls Source: https://github.com/shopify/shopify-api-ruby/blob/main/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md When specifying full paths for API calls in `find`, use `api_version.construct_api_path` to build the path instead of hardcoding `/admin`. ```ruby def self.current(options = {}) find(:one, options.merge( from: api_version.construct_api_path("shop.#{format.extension}") )) end ``` -------------------------------- ### Add Metafield to a Product Source: https://github.com/shopify/shopify-api-ruby/wiki/API-examples Creates and adds a new metafield to a product. Requires key, namespace, value, and value_type. ```ruby metafield = ShopifyAPI::Metafield.new(key: "desired_key", namespace: "your_app_name", value: "The content!", value_type: "string") product = ShopifyAPI::Product.first product.add_metafield(metafield) ``` -------------------------------- ### GraphQL Query with Variables Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/graphql.md Execute a GraphQL query that accepts variables. Define the query with placeholders for variables and pass a hash of variable values to the client's query method. ```ruby client = ShopifyAPI::Clients::Graphql::Admin.new(session: session) query = <<~QUERY query testQueryWithVariables($first: Int!){ products(first: $first) { edges { cursor node { id title onlineStoreUrl } } } } QUERY variables = { first: 3 } response = client.query(query: query, variables: variables) ``` -------------------------------- ### Configure and Use Active Session for API Calls Source: https://github.com/shopify/shopify-api-ruby/blob/main/docs/usage/oauth.md Activate a retrieved session using ShopifyAPI::Context.activate_session to allow API clients to use it automatically without explicit passing. This is useful for simplifying subsequent API calls. ```ruby #### Configuration def configure_app # This method is called before making authenticated API calls session = retrieve_session_from_file # your implementation of retrieving a session # Activate session to be used in all API calls # session must be type `ShopifyAPI::Auth::Session` ShopifyAPI::Context.activate_session(session) end #### Using clients to make authenticated API calls def make_api_request # 1. Create API client without session information # The graphql_client will use `ShopifyAPI::Context.active_session` when making API calls graphql_client = ShopifyAPI::Clients::Graphql::Admin.new # 2. Use API client to make queries ... end ```