Magento2 - Search parameters for the REST API

A how-to on curl PUT requests to search Magento2s REST API using search_criteria and filter_groups.

Searching for products with the REST API can be at the beginning pretty complex. These tips will hopefully help you.

These search criteria applies to all API classes/interfaces which implements the method: getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)

  • /V1/products
  • /V1/products/attributes
  • /V1/products/attribute-sets/sets/list
  • /V1/products/attribute-sets/groups/list
  • /V1/products/attribute-sets/:attributeSetId/groups
  • /V1/products/media/types/:attributeSetName
  • /V1/categories
  • /V1/categories/attributes
  • /V1/customerGroups/search
  • /V1/customers/search
  • /V1/eav/attribute-sets/list
  • /V1/orders
  • /V1/invoices
  • /V1/creditmemos
  • /V1/shipments
  • /V1/transactions
  • /V1/taxRate/search
  • /V1/taxRules/search
  • /V1/taxClass/search

The basic setup for the command line looks:

$ curl -X PUT -i \
-H 'Content-type: application/json' \
-d 'Enter here JSON Data' \
http://magento2.local/rest/V1/products

Array structure

{
    "search_criteria": {
        "filter_groups": [
            {
                "filters": [
                    {
                        "field": "attribute_name",
                        "value": [string|int|float],
                        "condition_type": [string]; optional
                    }
                    more entries
                ]
            }
            more entries
        ],
        "current_page": [int] page number; optional
        "page_size": [int] number of items on a page; optional
        "sort_orders": [ optional
            {
                "field": "attribute_name",
                "direction": [int] -1 or 1
            }
            more entries
        ]
    }
}
  • search_criteria: outer wrapper
  • filter_groups: wrapper for n filters
  • current_page: current page ;-)
  • page_size: number of items per result
  • sort_orders: array of fields and directions. Note: direction is either 1 (ASC) or -1 (DESC)

The direction of the sort_orders are defined in Magento\Framework\Api\SearchCriteriaInterface.

The conversion of the array structure into the SearchCriteriaInterface happens in: Magento\Webapi\Controller\ServiceArgsSerializer

Condition Types and Sorting

I’ll show here only two conditions on how to use them. Other possibilities are listed here:

lib/internal/Magento/Framework/Api/CriteriaInterface.php

Greater than and like queries

This query searches all products which price is (greater than 500 OR smaller than 10) AND name contains canon. It lists the first 10 results.

{
    "search_criteria": {
        "filter_groups": [
            {
                "filters": [
                    {
                        "field": "price",
                        "value": "500",
                        "condition_type": "gt"
                    },
                    {
                        "field": "price",
                        "value": "10",
                        "condition_type": "lt"
                    }
                ]
            },
            {
                "filters": [
                    {
                        "field": "name",
                        "value": "%canon%",
                        "condition_type": "like"
                    }
                ]
            }
        ],
        "current_page": 1,
        "page_size": 10
    }
}

The filters are merged the OR way. Here: price > 100 OR price < 10.

The filter_groups are merged the AND way.

like

{
    "search_criteria": {
        "filter_groups": [
            {
                "filters": [
                    {
                        "field": "name",
                        "value": "%computer%",
                        "condition_type": "like"
                    }
                ]
            }
        ],
        "current_page": 1,
        "page_size": 1
    }
}

Sorting

This query searches all products which price is greater than 100 and sorts them descending. It lists the first 10 results.

{
    "search_criteria": {
        "filter_groups": [
            {
                "filters": [
                    {
                        "field": "price",
                        "value": "100",
                        "condition_type": "gt"
                    }
                ]
            }
        ],
        "current_page": 1,
        "page_size": 10,
        "sort_orders": [
            {
                "field": "price",
                "direction": -1
            }
        ]
    }
}

Also the sorting for the price does not work. Because app/code/Magento/Catalog/Model/ProductRepository.php::getList() adds the price order to the collection but the internal mapper in method lib/internal/Magento/Framework/Data/Collection/Db.php::_setOrder() and there in the function _getMappedField() rewrites price to price_index.price. When the collection loads _renderOrders() adds all orders to the select() but ONLY if addAttributeToSort() can find the attribute in the join, static or attributes fields. And of course the price_index.price is not in there. We also have no possibility to extend the collection with other fields.

The query:

curl -X PUT -i -H 'Content-type: application/json' \
-d '{"search_criteria":{"filter_groups":[{"filters":[{"field":"price","value":"100","condition_type":"gt"}]}],"current_page":1,"page_size":10,"sort_orders":[{"field":"price","direction":-1}]}}' \
http://magento2.local/rest/V1/products

CustomAttributes

{
    "searchCriteria": {
        "filterGroups": [
            {
                "filters": [
                    {
                        "custom_attributes": [
                            {
                                "attribute_code": "weight",
                                "value": 100
                            }
                        ]
                    },
                    {
                        "field": "price",
                        "value": "10",
                        "condition_type": "lt"
                    }
                ]
            },
            {
                "filters": [
                    {
                        "field": "sku",
                        "value": "W2452T-TF"
                    }
                ]
            }
        ],
        "current_page": 1,
        "page_size": 10
    }
}

Despite following the structure for custom_attributes in a test for a customer … the filter does not work is always empty. I’ve tried some variations but that is so hard to debug :-(

Custom_attributes have assigned the interface Magento\Framework\Api\AttributeInterface which lacks of a method for the condition_type. Source That means you can only filter custom_attributes with eq, the default condition.

The curl command:

curl -X PUT -i -H 'Content-type: application/json' \
-d '{"searchCriteria":{"filterGroups":[{"filters":[{"custom_attributes":[{"attribute_code":"weight","value":100}]},{"field":"price","value":"10","condition_type":"lt"}]},{"filters":[{"field":"sku","value":"W2452T-TF"}]}],"current_page":1,"page_size":10}}' \
http://magento2.local/rest/V1/products | lynx -stdin

Yes I’m using lynx for debugging with var_dump because the xdebug debugger does not work :-(

Or I’ve just figured out this style:

curl \
	-X PUT \
	 -i -H 'Content-type: application/json' \
	--data @- \
	http://magento2.local/rest/V1/products <<EOP
{
    "searchCriteria": {
        "filterGroups": [
            {
                "filters": [
                    {
                        "custom_attributes": [
                            {
                                "attribute_code": "weight",
                                "value": 100
                            }
                        ]
                    }
                ]
            }
        ]
    }
}
EOP

If you don’t like the CLI you can use: http://www.getpostman.com/

Related posts