REST API
The REST API lets other programs — a mobile app, a warehouse system, a JavaScript site — work with the shop over HTTP and get responses in JSON. In Magento you do not write separate controllers for this: a URL is bound to a method of an interface from the Api folder. The review repository is already prepared for that.
Where the file lives
REST URLs are described in the module's etc/webapi.xml file. The file is created by hand.
app/code/Acme/Hello/
├── Api/
│ ├── Data/ReviewInterface.php
│ └── ReviewRepositoryInterface.php
└── etc/
├── module.xml
└── webapi.xml new fileReading a review
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/webapi.xml -->
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/hello/reviews/:id" method="GET">
<service class="Acme\Hello\Api\ReviewRepositoryInterface" method="getById"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>The entry binds the GET /V1/hello/reviews/5 request to the repository's getById() method. The :id part of the URL goes into the method parameter of the same name.
Run bin/magento cache:clean and send a request:
curl http://shop.test/rest/V1/hello/reviews/1The response is a review in JSON: {"id":1,"product_id":1,"author":"Anna","rating":5}. The fields come from the methods of the ReviewInterface interface: getProductId() became product_id. All REST URLs start with /rest.
Who may call it
The resource tag decides who can access a URL:
ref value | Who can access |
|---|---|
anonymous | Everyone, without logging in |
self | A logged-in customer, to work with their own data |
A permission from acl.xml | A staff member or an integration with that permission |
Creating a review
Add a second URL to webapi.xml, available only with the Acme_Hello::reviews permission:
<!-- app/code/Acme/Hello/etc/webapi.xml -->
<route url="/V1/hello/reviews" method="POST">
<service class="Acme\Hello\Api\ReviewRepositoryInterface" method="save"/>
<resources>
<resource ref="Acme_Hello::reviews"/>
</resources>
</route>The request body is a JSON object whose keys match the method parameter names. The parameter of save() is called $review, so the review is passed under the review key.
A request with a token
Protected URLs require an access token. On a local copy the easiest way to get one is with the administrator's username and password:
curl -X POST http://shop.test/rest/V1/integration/admin/token \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "Secret123"}'The response is a string with the token. Pass it in the Authorization header:
curl -X POST http://shop.test/rest/V1/hello/reviews \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN" \
-d '{"review": {"product_id": 1, "author": "Maria", "rating": 5}}'Magento creates a ReviewInterface object, fills it with the setProductId(), setAuthor(), setRating() methods and passes it to save(). The response contains the saved review with its ID. Without the header the server answers with a 401 error.
When two-factor login is enabled, a token is not issued by password alone. For permanent integrations a token is created in the admin panel: System → Integrations.
The list of URLs
All REST URLs of the shop, including yours, are shown by the built-in documentation page http://shop.test/swagger. Core URLs work the same way: for example, GET /rest/V1/products/24-MB01 calls the get() method of the product repository.
Common mistake
For the getList() method from the repositories lesson the request returns empty objects. The generic SearchResultsInterface does not know that the list holds reviews. To return a list through REST, create your own search results interface in Api/Data whose getItems() comment states the \Acme\Hello\Api\Data\ReviewInterface[] type — all core repositories are built this way.