woocommerce / woocommerce-rest-api

This is the WooCommerce core REST API Package. It runs standalone as a feature plugin too.
71 stars 46 forks source link

Getting products with variation details in bulk? #254

Closed raoulalwani closed 3 years ago

raoulalwani commented 3 years ago

Hi all,

Adding an integration for WooCommerce to our app, sellers are using our system to manage all their inventory.

I'm using the REST API (in Ruby) as documented here: https://woocommerce.github.io/woocommerce-rest-api-docs/#list-all-products

We need to retrieve the list of products + variations (including details) for our sellers. I can get the products with minimal API calls by using the total_number to enumerate:

while current_position < total_products_count
  get("products", :per_page => 100, :offset => current_position).parsed_response
  current_position += 100
end

However the variations array for each product object is just showing the ID: "variations"=>[5993]

I tried using the include param for get products again to minimise calls:

get("products", :include => variation_ids, :per_page => 100, :offset => current_position).parsed_response

But variations are not retrieved with this endpoint so the results are empty.

To be clear, if id=5993 is a variation, then:

get("products/5993").parsed_response

works and retrieves the data, but

get("products", :include => [5993]).parsed_response

does not.

How can I get the full list of variations with details without pinging the server for each product? The only relevant call I can see is woocommerce.get("products/22/variations").parsed_response but that is impractical to cycle through hundreds if not thousands of products to get details for each variant separately.

Any options for this? We don't have access to modify anything on the server, we have to use the vanilla API.

raoulalwani commented 3 years ago

Temporary solution for anyone else that comes across this issue: Use the legacy API and the following code:

# Ruby solution
gem "woocommerce_api"

# Init the object:
woocommerce = WooCommerce::API.new(
  site_url,
  woocommerce_key,
  woocommerce_secret,
  {
    version: "v3" # note, DO NOT pass in wc_api:true else you'll end up back at the current REST API. 
  }
)

total_product_count = woocommerce.get("products/count").parsed_response["count"]
# Requesting 100 per page, so depending on the total_products, page through to get total product list
current_position = 0
current_page = 1
while current_position < total_product_count
  products = woocommerce.get("products?filter[limit]=100&page=#{current_page}").parsed_response["products"]
  current_position += 100
  current_page += 1
  # do whatever with the products, eg: add to a total_products array, etc. 
end

I don't like mixing the two APIs, but this is a stop-gap solution until a better endpoint is released in the next version. This is still preferable to pinging the server hundreds or thousands of times to get all the variation details if you need to grab the full product listings.