-
Notifications
You must be signed in to change notification settings - Fork 7
Tips & Tricks
When the server is Apache and paths starting with /api/rest/...
give an unhelpful message like this:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://example.com/?wsdl=1' : Entity 'copy' not defined
This is caused by mod_negotiation
turning /api
into /api.php
and bypassing the necessary rewrite rule. Magento's Api2 module doesn't get the rest
part and falls back to using SOAP instead. The fix is simpler than the cause, just uncomment this line in the .htaccess
file:
Options -MultiViews
Magento's API assumes Accept: */*
means to return JSON, which is convenient for us. RFC 2616 says:
If no Accept header field is present, then it is assumed that the client accepts all media types.
Magento does not understand a missing header to be the same as Accept: */*
which is less than convenient.
If you request fewer attributes then the server has less work to do and less data to transmit. It is not necessary to adjust settings in "System > Web Services > REST - Attributes". Instead, have your client add an attrs
query parameter. For example, the minimum data you need to build a menu might just be:
GET /api/rest/category_trees?attrs=name,url
The response is then something like this:
[
{
"name": "Default Category",
"children": [
{
"name": "Women",
"url": "http://example.com/women.html",
"children": [
{
"name": "Tops & Blouses",
"url": "http://example.com/women/tops-blouses.html"
},
{
"name": "Pants & Denim",
"url": "http://example.com/women/pants-denim.html"
},
{
"name": "Dresses & Skirts",
"url": "http://example.com/women/dresses-skirts.html"
},
{
"name": "New Arrivals",
"url": "http://example.com/women/new-arrivals.html"
}
]
},
...etc.
API filters have an arcane syntax due to their reliance on PHP array structures and can cause headaches. Automate this if possible. For example, to exclude "Default Category" from the above example:
<?php
$query = http_build_query([
'attrs' => ['name', 'url'],
'filter' => [
['attribute' => 'level', 'gt' => 1],
// more filters here are ANDed together
]
]);
echo '/api/rest/category_trees?', $query;
This produces an unwieldily looking string (/api/rest/category_trees?attrs%5B0%5D=name&attrs%5B1%5D=url&filter%5B0%5D%5Battribute%5D=level&filter%5B0%5D%5Bgt%5D=1
) but the result is perfect:
[
{
"name": "Women",
"url": "http://example.com/women.html",
"children": [
{
"name": "Tops & Blouses",
"url": "http://example.com/women/tops-blouses.html"
},
{
"name": "Pants & Denim",
"url": "http://example.com/women/pants-denim.html"
},
{
"name": "Dresses & Skirts",
"url": "http://example.com/women/dresses-skirts.html"
},
{
"name": "New Arrivals",
"url": "http://example.com/women/new-arrivals.html"
}
]
},
...etc.
The filter used above isn't well explained and the official documents don't do a better job. The necessary array syntax is best explained in Varien Data Collections by Alan Storm.
Responses are cached more efficiently when there is no Authorization
header. If a customer's view of a resource is the same as a guest's, such as with categories, then it is preferable to only request as a guest user.