Skip to content

Sorting ​

How to sort and filter list endpoints. The mechanics are the same across every Shop list, so endpoint pages don't repeat them.

Sorting ​

REST ​

Two accepted forms — compound token or split params:

GET /api/shop/products?sort=name-asc
GET /api/shop/products?sort=name&order=desc
Sort fieldToken examples
namename-asc, name-desc
priceprice-asc, price-desc
created_atcreated_at-asc, created_at-desc
updated_atupdated_at-asc, updated_at-desc
idid-asc, id-desc

String sorts are case-insensitive.

Example — cheapest first:

bash
curl -X GET "https://your-domain.com/api/shop/products?sort=price-asc&per_page=2" \
  -H "X-STOREFRONT-KEY: pk_storefront_xxxxxxxxxxxxx"
json
[
  { "id": 7, "sku": "BASICTEE", "name": "Basic Tee", "price": "12.00" },
  { "id": 3, "sku": "CANVASCAP", "name": "Canvas Cap", "price": "15.00" }
]

GraphQL ​

graphql
query {
  products(sortKey: PRICE, reverse: false, first: 2) {
    edges {
      node {
        id
        name
      }
    }
  }
}
json
{
  "data": {
    "products": {
      "edges": [
        { "node": { "id": "/api/shop/products/7", "name": "Basic Tee" } },
        { "node": { "id": "/api/shop/products/3", "name": "Canvas Cap" } }
      ]
    }
  }
}

sortKey is the field in upper-case (NAME, PRICE, CREATED_AT, UPDATED_AT, ID); reverse: true = descending. So REST ?sort=price-desc ≡ GraphQL sortKey: PRICE, reverse: true.

Filtering (products) ​

REST — query-string params ​

GET /api/shop/products?type=configurable&category_id=2&price=10,200&new=1
FilterParam
Search termquery
Typetype (simple / configurable / …)
Categorycategory_id
Price rangeprice=<from>,<to> — or price_from + price_to
New / Featurednew=1 / featured=1
Attribute (e.g. colour, size)color=<optionId>, size=<optionId> — any filterable attribute code

Multiple filters combine with AND. Any query-string key that isn't a reserved one (query, sort, order, page, per_page, locale, channel, filter) is treated as an attribute filter.

GraphQL — a JSON filter string ​

The same filters go into a single JSON-encoded filter argument:

graphql
products(filter: "{\"type\":\"configurable\",\"category_id\":2,\"price\":\"10,200\",\"new\":1}") {
  edges {
    node {
      id
      name
    }
  }
}

This is the one shape that does not carry over literally between transports — REST spreads filters across query params, GraphQL packs them into the filter string.

Category children — a common trip-up ​

REST fetches a category's children with ?parent_id=<id>. GraphQL has no parentId argument on categories — children come from treeCategories(parentId: <id>). Sending the REST shape into the GraphQL categories field returns everything, not the children.

Released under the MIT License.