Magento 2: Wstęp do REST API
Z racji tego, że istnieje potrzeba udostępniania systemu i jego danych innym systemom zewnętrznym, Magento oferuje różnego rodzaju API, które implementuje większość podstawowych funkcji. Magento 2 dostarcza nam REST API i SOAP — oba obsługiwane są przez to same klasy.
Co to jest REST API?
Magento 2 REST API udostępnia różne funkcje, które pozwalają na wykonanie żądań i otrzymania odpowiedzi. Pomimo że sam w sobie REST jest stylem architektonicznym i teoretycznie nie jest zależny od protokołu. W praktyce jednak interakcja odbywa się przez protokół HTTP.
Klient wysyła żądanie HTTP, które zawiera poniższe elementy:
- Nagłówek HTTP, który dostarcza nie tylko dane uwierzytelniające, ale także inne instrukcje,
- Typ żądania kierowany do endpointa, może to być GET, POST, PUT lub DELETE,
- Endpoint jest to ujednolicony identyfikator zasobów (ang. URI — Uniform Resource Identifier),
- Wywołanie bloki danych (ang. payload) zawiera zestaw parametrów wejściowych i atrybutów, które są dostarczane wraz z żądaniem.
Blok danych oraz status HTTP zostanie zwrócony w odpowiedzi.
Nagłówki HTTP
Nagłówek | Składnia | Opis |
Authorization (wymagany) | Authorization: Bearer <token> | Określa token uwierzytelniający, który potwierdza, że jesteś uprawionym użytkownikiem Magento. Potrzebujemy w nagłówku żądania określić za pomocą bearer tokena. |
Accept (opcjonalny) | Accept: application/json | Określa format odpowiedzi JSON lub XML, domyślny format to JSON. |
Content-Type (Wymagany, gdy przez żądanie wysyłamy dane) | Content-Type: application/json | Określa format przysyłanych danych: JSON lub XML. |
HTTP verb
- GET — pobieranie docelowego zasobu przez podanie jego identyfikatora,
- POST — tworzy nowy zasób, umożliwia pobieranie danych w ramach dostarczenia danych w treści żądania, używany jeśli inne operacje nie pasują do użytku,
- PUT — aktualizuje nowy zasób. Może też być wykorzystywana do tworzenia nowego zasobu jeśli znany jest jej identyfikator. Żądanie utworzenia stanu zasobu docelowego lub zastąpienia go stanem, który jest zdefiniowany przez zawartą w bloku wiadomości żądania,
- DELETE — żądanie, które obsługuje usuwanie określonego zasobu przez identyfikator,
- PATCH — żądanie, które aktualizuje część wskazanego zasobu (i ta część właśnie odróżnia go od żądania typu PUT). Adapter Magento nie wspiera w tym momencie metody PATCH — mamy tu wątek na github, gdzie mamy informację o tym, że musimy rozszerzyć klasę Magento\Framework\HTTP\Adapter\Curl od obsługi takiego rodzaju żądania i użyć jej we własnym kodzie.
Obsługiwane formaty
REST API obsługuje następujące formaty:
- JSON — JavaScript Object Notation,
- XML — Extensible Markup Language.
Endpoint
Punkt końcowy, który bardzo często nazywany jest endpointem, określa dostęp do zasobu. Najczęściej adres usługi ma następującą strukturę:
http://<adres-serwera>:<port-aplikacji>/<endpoint>
Jeśli chodzi o Magento 2 dostęp do przykładowego zasobu:
https://shop-page.local/rest/<store_code>/V1/cmsPage/{id}
- rest — ścieżka określająca typ serwisu, tutaj REST API,
- <store_code>— kod store przypisany do sklepu, domyślnie jest to default,
- /V1/cmsPage — jest zasobem, do którego chcemy uzyskać dostęp,
- {id} – id zasobu, dla wspomnianego endpointa jest to argument szablonowy.
Kod sklepu może przyjmować następujące wartości:
- kod sklepu – przypisany do strony sklepu. Kod sklepu jest przechowywany w tabeli store w kolumnie code. Domyślnie mamy dwa kody: admin i default.
- default — wartość domyślna gdzie kod sklepu nie jest wprowadzony,
- all — tylko dla enpointów dla modułów związanych ze stronami CMS i produktami. Takie żądanie API będzie miała efekt na wszystkie sklepy.
Listę poszczególnych endpointów znajdziesz na stronie https://developer.adobe.com/commerce/webapi/rest/quick-reference
Rodzaje tokenów w Magento 2
W zależności jaki rodzaj tokena potrzebujemy uzyskać, wybieramy odpowiedni endpoint:
Typ tokena | Odpytanie | Czas Ważności (godziny) |
Admin | POST V1/integration/admin/token | 4 |
Admin z Google Authenticator | POST /V1/tfa/provider/google/authenticate | 4 |
Admin z Duo Security | POST /V1/tfa/provider/duo-security/authenticate | 4 |
Admin z Authy | POST /V1/tfa/provider/authy/authenticate | 4 |
Admin z U2F | POST /V1/tfa/provider/u2fkey/verify | 4 |
Customer (self lub anonymous) | POST /V1/integration/customer/token | 1 |
Integration | Request token (tymczasowy token): POST /oauth/token/request który wymieniamy na access token: POST /oauth/token/access Jak wykonać odpytanie znajdziesz informację tutaj. | Nieokreślony |
W zależności od typu użytkownika, wygenerowany token, który daje nam konkretne dostępy. Użytkownik Guest, nie ma ustawionego tokena.
Konfiguracja endpointa i dostępów do niego w module
Definicja poszczególnych endpointów znajdziemy w pliku konfiguracyjnym webapi.xml, który jest umieszczony w folderze etc danego modułu. Plik zawiera definicję ścieżki route wraz z całą konfiguracją dotyczącą endpointa ścieżki, zasobu, parametrów itd.
Poniżej przykładowa definicja endpointa z modułu Magento_Checkout. Mamy endpoint, który obsługuje obliczanie sum dla zamówienia:
- Magento_Cart::manage – dla administratora, który powinien mieć przypisany dostęp do zasobu w konfiguracji. Jest to reguła ACL, której konfiguracja znajduję się w pliku etc/acl.xml modułu,
- self – odnosi się do zasobu, do którego ma dostęp obecny, zalogowany użytkownik,
- anonymous – takie endpointy odnoszą się do anonimowego użytkownika. Użytkownik, gość, to taki użytkownik, który nie został zautoryzowany poprzez ustawienie tokena.
- Węzeł <route> (wymagany), który posiada następujące atrybuty:
- method (wymagany) – nazwa metody HTTP, dozwolone wartości to: GET, POST, PUT i DELETE,
- url (wymagany) – url do zasobu, w stylu /V1/products/:sku, gdzie :sku jest parametrem do podstawienia,
- secure (opcjonalny) – true/false, określa czy podana ścieżka jest dostępna tylko przez https,
- soapOperation (opcjonalny) – do określenia nazwy operacji dla SOAP, która jest inna niż nazwa metody interfejsu. Ustawiamy, gdy potrzebujemy określić wiele operacji dla tego samego kontraktu serwisowego.
- Węzeł <service> (wymagany), element potomny węzła <route>. Posiada atrybuty:
- class (wymagany) – interfejs klasy,
- method (wymagany) – nazwa metody do wykonania.
- Węzeł <resources> (wymagany), stanowi element potomny węzła <route>. Jest to kontener dla konfiguracji dostępu,
- Węzeł <resource> (wymagany), element potomny węzła <resources>. Posiada atrybut:
- ref (wymagany) – jako referencja do wartości określającej rodzaj dostępu do zasobu. Dozwolone wartości to self, anonymous lub nazwa reguły ACL na przykład Magento_Cart::manage.
- Węzeł <data> (opcjonalny), element potomny węzła <route>. Jest kontenerem dla jednego lub wiele definicji parametrów,
- Węzeł <parameter> (wymagany, gdy węzeł <data> jest określony), element potomny węzła <data>:
- name – nazwa parametru,
- force – true/false. Daje pewność, że dana wartość będzie wymuszona. W przykładzie dla definicji dostępu z self mamy określony parametr cartId, który musi odpowiadać identyfikatorowi koszyka obecnie zalogowanego użytkownika.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?xml version="1.0"?> <!-- /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ --> <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd"> <!-- (...) --> <!-- Managing totals information --> <route url="/V1/carts/:cartId/totals-information" method="POST"> <service class="Magento\Checkout\Api\TotalsInformationManagementInterface" method="calculate"/> <resources> <resource ref="Magento_Cart::manage" /> </resources> </route> <!-- Managing guest totals information --> <route url="/V1/guest-carts/:cartId/totals-information" method="POST"> <service class="Magento\Checkout\Api\GuestTotalsInformationManagementInterface" method="calculate"/> <resources> <resource ref="anonymous" /> </resources> </route> <!-- Managing My totals information --> <route url="/V1/carts/mine/totals-information" method="POST"> <service class="Magento\Checkout\Api\TotalsInformationManagementInterface" method="calculate"/> <resources> <resource ref="self" /> </resources> <data> <parameter name="cartId" force="true">%cart_id%</parameter> </data> </route> <!-- (...) --> </routes> |
W zależności od typu użytkownika, mamy inny endpoint, lecz także określony inny rodzaj dostępu do zasobu:
Elementy konfiguracyjne webapi.xml:
Konfiguracja roli dla REST API
Do stworzenia roli w Magento 2 potrzebujemy zalogować się do admina, gdzie z menu wchodzimy System ⮞ User Roles.
Klikamy na przycisk Add New Role. W pierwszej zakładce formularza wpisujemy nazwę roli oraz hasło obecnie zalogowanego konta.
Następnym krokiem jest określenie zasobów, dla których dodana rola będzie miała dostęp. Dla ustawienia Resource Access mamy dwie opcje do wyboru:
- All,
- Custom.
Opcja Custom pozwala nam na wybranie konkretnych zasobów dla tworzonej roli użytkownika:
Stworzoną rolę możemy teraz przypisać wybranemu użytkownikowi.
Aby stworzyć użytkownika lub przypisać nową rolę istniejącemu użytkownikowi, potrzebujemy wejść w menu System ⮞ All Users.
W formularzu edycji, w zakładce User Role wybieramy interesującą nas rolę do przypisania.
Wykonanie zapytania do Magento 2 REST API
Wykonajmy teraz zapytanie REST API do Magento 2. Do wykonania zapytań możesz użyć narzędzia POSTMAN, stworzyć zapytania za pomocą CURL-a, a następnie je zaimportować.
Przykłady, które przedstawie w dalszej części, możesz łatwo zaimportować do POSTMAN-a.
Uwierzytelnienie użytkownika
Pierwszą rzeczą jest odpytanie endpointa o token, aby na podstawie danych naszego konta użytkownika wygenerować token, który pozwoli uzyskać dostęp do uprawnionych zasobów. W zależności od typu tokena potrzebujemy odpytać inny endpoint.
Odpytanie o token bez włączonego 2FA wykonujemy za pomocą integration/admin/token:
1 2 3 |
curl -k -X POST https://magento.test/rest/default/V1/integration/admin/token \ -H "Content-Type: application/json" \ -d '{"username":"ania","password":"password"}' |
W przypadku, gdy mamy włączone 2FA, od Googla, potrzebujemy wykorzystać endpoint: tfa/provider/google/authenticate.
1 2 3 |
curl -k -X POST https://magento.test/rest/default/V1/tfa/provider/google/authenticate \ -H "Content-Type: application/json" \ -d '{"username":"ania","password":"password","otp": "425223"}' |
W przykładzie parametr otp jest tymczasowym, 6-cyfrowym hasłem, które musimy przepisać w używanej przez na aplikacji na przykład z Authy.
Przykładowa odpowiedź zwraca token:
1 |
eyJraWQiOiIxIiwiYWxnIjoiSFMyNTYifQ.eyJ1aWQiOjIsInV0eXBpZCI6MiwiaWF0IjoxNzAzODk5MDU1LCJleHAiOjE3MDM5MDI2NTV9.nV1RF_0C-kMRwSxGn3msXoOqBZbKqM5bKYN1d21AIKY |
Przykładowe odpytanie o stronę CMS
Wygenerowany token możemy następnie użyć przy zapytaniu o dostępne zasoby. Wypytajmy Magento o zwrócenie informacji na temat konkretnej strony CMS.
W celu wykonania zapytania jako użytkownik admin potrzebujemy do zapytania określić nagłówek Authorization i ustawić mu wygenrowany token. W CURL-u odpowiada za to opcja -H:
1 2 3 |
curl -k -X GET https://magento.test/rest/default/V1/cmsPage/6 \ -H "Authorization: Bearer eyJraWQiOiIxIiwiYWxnIjoiSFMyNTYifQ.eyJ1aWQiOjIsInV0eXBpZCI6MiwiaWF0IjoxNzAzODk5MDU1LCJleHAiOjE3MDM5MDI2NTV9.nV1RF_0C-kMRwSxGn3msXoOqBZbKqM5bKYN1d21AIKY" -H "Content-Type: application/json" |
Magento 2 zwraca nam odpowiedź:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Fri, 29 Dec 2023 02:24:52 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive X-Powered-By: PHP/8.2.12 X-Frame-Options: SAMEORIGIN Cache-Control: no-store Vary: Accept-Encoding { "id": 6, "identifier": "customer-service", "title": "Customer Service", "page_layout": "1column", "meta_keywords": "", "meta_description": "", "content_heading": "Customer Service", "content": "<div class=\"customer-service cms-content\">\n <div class=\"cms-content-important\">\n <h2>Luma Delivery and Returns<\/h2>\n <p>We hope you love shopping with Luma. Here are our delivery and returns policies to help make sure we meet your expectations. <a href=\"{{store url=\"contact\"}}\">Contact Us.<\/a><\/p>\n <\/div>\n\n <h2>Shipping and Delivery<\/h2>\n <p>Shipping and Delivery is the charge for internet order processing, item selection, packaging, transport and handling. We don’t guarantee delivery times, but we do our best to provide accurate estimates.<\/p>\n\n <p>Deliveries occur only on weekdays. Shipping and Delivery charges are subject to change and are determined when you order. Estimated delivery time assumes orders are placed before 12:00 noon (PST). Orders you place with Luma late on Friday or on Saturday will not be processed until Monday. Charges may be added to orders with Priority, Overnight and International shipping if we try unsuccessfully to deliver your order more than once.<\/p>\n\n <p>Delivery addresses in Alaska, Hawaii, Puerto Rico, and Guam should add an additional $5.00 charge for standard Shipping & Delivery. Orders arrive in 7 to 9 business days when ordered before 12:00 noon (PST).<\/p>\n\n <div class=\"table-wrapper\">\n <table>\n <caption>Shipping and Delivery<\/caption>\n <thead>\n <tr>\n <th><strong>Merchandise total *<\/strong><\/th>\n <th><strong>STANDARD<\/strong><br \/>5&mdash;7 day shipping **<\/th>\n <th><strong>PRIORITY<\/strong><br \/>2&mdash;3 day shipping **<\/th>\n <th><strong>OVERNIGHT<\/strong><br \/>Next business day **<\/th>\n <\/tr>\n <\/thead>\n <tbody>\n <tr>\n <th>Up to $200<\/th>\n <td>$16<\/td>\n <td>$26<\/td>\n <td>$33<\/td>\n <\/tr>\n <tr>\n <th>$200.01&mdash;500.00<\/th>\n <td>$21<\/td>\n <td>$31<\/td>\n <td>$38<\/td>\n <\/tr>\n <tr>\n <th>$500.01&mdash;1000.00<\/th>\n <td>$29<\/td>\n <td>$39<\/td>\n <td>$46<\/td>\n <\/tr>\n <tr>\n <th>Over $1000.00<\/th>\n <td>$34<\/td>\n <td>$44<\/td>\n <td>$51<\/td>\n <\/tr>\n <\/tbody>\n <\/table>\n <\/div>\n\n <p>\n <small>*before tax and additional charges<\/small><br \/>\n <small>**after processing if ordered by 12:00 noon PST<\/small>\n <\/p>\n\n <h2 style=\"margin-top: 40px;\">Returns and Replacements<\/h2>\n <p>We want you to be completely happy with your Luma order. If for any reason you are not satisfied, we will gladly accept your timely return of unworn, unwashed, or defective merchandise. Used merchandise cannot be returned unless defective. Returned merchandise should include the vendor packaging and tags and be in the same condition as when it was received. A pickup and\/or restock fee may apply. Merchandise must be returned within 30 days of receipt of merchandise.<\/p>\n\n <h3>Returning Gifts<\/h3>\n <p>When returning a gift, a Luma Gift Card will be issued to the gift recipient for the amount of the returned merchandise. The card can be used for purchases from any Luma store, and online. In compliance with Federal law, for gifts valued at more than $2,000.00, the recipient will receive a check rather than an Luma Gift Card.<\/p>\n\n <h3>Returning Merchandise by Mail<\/h3>\n <p>On the back of the packing slip enclosed with your Luma order, please note the reason(s) for return and whether you wish to exchange the item(s) or receive a credit\/refund (depending on the original form of payment).<\/p>\n <p>Enclose the return section of the packing slip with your item(s). Please use one of the return labels provided on the front of your packing slip to ensure proper return address and credit information. Restricted items must be returned using ground transportation.<\/p>\n <p>Please allow 10 to 14 days for Luma to process your return.<\/p>\n<\/div>\n", "creation_time": "2023-12-25 01:49:05", "update_time": "2023-12-25 01:49:05", "sort_order": "0", "layout_update_xml": "", "custom_theme": "", "custom_root_template": "", "active": true } Response code: 200 (OK); Time: 266ms; Content length: 4647 bytes |