Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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 file

Reading 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/1

The 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 valueWho can access
anonymousEveryone, without logging in
selfA logged-in customer, to work with their own data
A permission from acl.xmlA 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.

Thanks for reading!

Donate to the site — we work hard for you.