skip to Main Content

I would like to ask about shopify pagination version 2020-01

First request query:
URL: https://klevarange.myshopify.com/admin/api/2020-01/orders.json?fulfillment_status=unfulfilled&limit=250&financial_status=paid&created_at_min=2019-08-27T16:15:47-04:00

Return Header:

"<https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info=eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzIxNzM2NTIsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjA5OjUyIiwiZGlyZWN0aW9uIjoibmV4dCJ9>; rel="next""

2nd Request Query:

"https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info=eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzI1MzQxMDAsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjEwOjA3IiwiZGlyZWN0aW9uIjoibmV4dCJ9>; rel="next""

Result: Bad Request

What should I put in page_info? Do I need to include the rel="next"" in the page_info?

Thank you.

3

Answers


  1. You should use only this part: https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info=eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzI1MzQxMDAsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjEwOjA3IiwiZGlyZWN0aW9uIjoibmV4dCJ9 i.e. without rel="next"

    In the 2nd and all next requests, you can only pass up to 3 query parameters:

    • page_info
    • limit
    • fields

    So if you want to get results from the next page you need to extract page_info value from the first response headers.

    The idea is that you can move only forward or backwards while requesting the results and you can get the link (page_info token) to the next (or previous) page only after retrieving the current page results.

    Login or Signup to reply.
  2. Remove > from your page_info variable

    var page_info = "eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzI1MzQxMDAsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjEwOjA3IiwiZGlyZWN0aW9uIjoibmV4dCJ9"
    

    and Make your request URL like below.

    https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info={page_info}

    Digging Deeper

    You need to iterate your while loop until there is no Link Parameter in the response header and this parameter is not a static value it is the address of last object you get and saying next will give you next 250 objects.

    you need to update your pageInfo parameter in every request with newly generated next reference ( pageInfo )

    enter image description here

    When you do not get this parameter that means there is no next or previous page .

    Have a look in this below code…( written in php )

    How to create pagination in shopify rest api using php

    Login or Signup to reply.
  3. Maybe in the last 2 years, Shopify has made some modifications to their API, then I use GetNextPageFilter method. This is my approach.

    public async Task<IEnumerable<Product>> ProductsGetList(string shopUrl, string accessToken)
        {
            var products = new List<Product>();
            var service = new ProductService(shopUrl, accessToken);
    
            var filter = GetFilters(shopUrl);
            var productList = await service.ListAsync(filter);
    
            if (productList != null && productList.Items.Any())
            {
                products.AddRange(productList.Items);
                bool hasMorePages = productList.HasNextPage;
                if (hasMorePages)
                {
                    do
                    {
                        var filterList = productList.GetNextPageFilter(filter.Limit, filter.Fields);
                        productList = await service.ListAsync(filterList);
    
                        if (productList != null && productList.Items.Any())
                        {
                            products.AddRange(productList.Items);
                            hasMorePages = productList.HasNextPage;
                        }
                    } while (hasMorePages);
                }
    
            }
    
    
            return products;
        }
    
    private ProductListFilter GetFilters(string url)
        {
            ProductListFilter filters = new ProductListFilter();
    
            string queryString = new System.Uri(url).Query;
            var queryDictionary = System.Web.HttpUtility.ParseQueryString(queryString);
    
            foreach (var parameter in queryDictionary)
            {
                var key = (string)parameter;
                var value = queryDictionary.Get(key);
                switch (key)
                {
                    case "published_status":
                        filters.PublishedStatus = value;
                        break;
                    case "published_at_max":
                        filters.PublishedAtMax = DateTimeOffset.Parse(value); 
                        break;
                    case "published_at_min":
                        filters.PublishedAtMin = DateTimeOffset.Parse(value);
                        break;
                    case "updated_at_max":
                        filters.UpdatedAtMax = DateTimeOffset.Parse(value);
                        break;
                    case "updated_at_min":
                        filters.UpdatedAtMin = DateTimeOffset.Parse(value);
                        break;
                    case "created_at_max":
                        filters.CreatedAtMax = DateTimeOffset.Parse(value);
                        break;
                    case "presentment_currencies":
                        filters.PresentmentCurrencies = value.Split(',').AsEnumerable();
                        break;
                    case "created_at_min":
                        filters.CreatedAtMin = DateTimeOffset.Parse(value);
                        break;
                    case "status":
                        filters.Status = value;
                        break;
                    case "product_type":
                        filters.ProductType = value;
                        break;
                    case "handle":
                        filters.Handle = value; 
                        break;
                    case "vendor":
                        filters.Vendor = value;
                        break;
                    case "title":
                        filters.Title = value;
                        break;
                    case "since_id":
                        filters.SinceId = long.Parse(value);
                        break;
                    case "collection_id":
                        filters.CollectionId = long.Parse(value);
                        break;
                    case "ids":
                        filters.Ids = value.Split(',').AsEnumerable().Cast<long>();
                        break;
                    case "limit":
                        filters.Limit = int.Parse(value);
                        break;
                }
            }
    
            return filters;
        }
    

    Where shopUrl is the entire URL (https://{apiKey}:{password}@{hostname}/admin/api/{version}/{resource}.json) and accessToken is the URL {password} atribute

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search