Blog

Primi passi con l’utilizzo delle API di Magento 2

Lettura 6 minuti

In questo articolo diamo uno sguardo ai cambiamenti avvenuti nell’utilizzo delle API in Magento 2 e forniremo qualche esempio pratico di integrazione.

Cosa è cambiato?

I protocolli supportati sono soltanto SOAP e REST, è stato eliminato XML-RPC ma la grossa novità è che, a differenza di quanto accadeva in Magento 1, a livello funzionale i due protocolli ora sono del tutto equivalenti.

Mentre infatti in Magento 1 le API REST offrivano un insieme funzionale più limitato rispetto a SOAP, con Magento 2 tale differenza è sparita.

Un altro cambiamento riguarda il fatto che in Magento 2 i ruoli e gli utenti di backend non sono più distinti da quelli delle API ed è inoltre possibile utilizzare le credenziali di un utente customer; in questo ultimo caso, però, funzionalità e visibilità dei dati risultano limitate.

Come effettuare i primi test

Prima di avventurarsi nella scrittura di codice di integrazione, consiglio di verificare che tutto funzioni sfruttando dei client REST e SOAP.

Per REST il client che suggerisco di utilizzare è Postman una Chrome application davvero ben fatta e liberamente utilizzabile.

Se operate su piattaforme Unix-based potete anche utilizzare il comando curl da linea di comando; è sicuramente meno pratico ma molto utile per documentare gli esempi di chiamate, proprio come farò io in questo articolo.

Per SOAP un client molto valido è rappresentato invece da SoapUI anch’esso liberamente utilizzabile e cross-platform.

Integrazione tramite REST

Per invocare le API REST è necessario utilizzare un token di autorizzazione, generato tramite una chiamata HTTP specifica.

Per generare il token è necessario possedere credenziali di accesso di backend (utente amministratore) o di frontend (utente customer).

Per l’accesso alle API con un utente di backend basterà definire il ruolo e la coppia di credenziali (username e password) rispettivamente in

System > Permissions > User Roles e in System > Permissions > All Users.

Per l’accesso alle API con un utente customer dovranno essere utilizzate le credenziali di un customer definito in Customers > All Customers.

Una volta identificate le credenziali da utilizzare possiamo generare il token.

Di seguito un esempio di chiamata curl per la generazione del token di backend per un utente amministratore il cui username è my_username e la password my_password:

curl -X POST "http://hostname/index.php/rest/V1/integration/admin/token" \
     -H "Content-Type:application/json" \
     -d '{"username":"my_admin", "password":"my_password"}'

Di seguito un esempio di chiamata curl per la generazione del token di frontend per un customer il cui username è my_customer e la password my_password:

curl -X POST "http://hostname/index.php/rest/V1/integration/customer/token" \
     -H "Content-Type:application/json" \
     -d '{"username":"my_customer", "password":"my_password"}'

Negli esempi precedenti le credenziali sono passate come parametri in formato JSON; è possibile inviare i parametri anche in formato XML, modificando il Content-Type e il corpo della richiesta, come mostrato di seguito:

curl -X POST "http://hostname/index.php/rest/V1/integration/admin/token" \
     -H "Content-Type:application/xml" \
     -d '<login><username>my_admin</username><password>my_password</password></login>'

Di seguito invece un esempio in PHP che sfrutta la Client URL Library e codifica i parametri in formato JSON:

<?php
function getAuthToken($hostname, $username, $password)
{
    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => "http://$hostname/index.php/rest/V1/integration/admin/token",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_POSTFIELDS => json_encode(['username' => $username, 'password' => $password]),
        CURLOPT_HTTPHEADER => [
            "cache-control: no-cache",
            "content-type: application/json",
        ],
    ]);

    $response = curl_exec($curl);
    $err = curl_error($curl);

    curl_close($curl);

    if ($err) {
        throw new Exception($err);
    } else {
        return json_decode($response, true);
    }
}

Una volta ottenuto il token (un hash code simile a: v8x520f9xup56i4jcmxm5vv44yvihw5c), è possibile utilizzarlo come descritto nei paragrafi successivi.

L’elenco completo dei servizi disponibili è documentato qui: http://devdocs.magento.com/guides/v2.0/rest/list.html

Utilizzo di curl da linea di comando

La seguente chiamata recupera le informazioni del customer il cui ID è 1:

    curl -X GET "http://hostname/index.php/rest/V1/customers/1" \
         -H "Authorization: Bearer v8x520f9xup56i4jcmxm5vv44yvihw5c"

Il risultato è in formato JSON, riportato di seguito e formattato per renderlo leggibile:

    {
      "id": 1,
      "group_id": 1,
      "default_billing": "1",
      "default_shipping": "1",
      "created_at": "2010-01-11 16:02:55",
      "updated_at": "2014-02-17 13:22:08",
      "created_in": "Default Store View",
      "email": "johndoe@example.com",
      "firstname": "John",
      "lastname": "Doe",
      "middlename": "",
      "prefix": "",
      "suffix": "",
      "store_id": 1,
      "taxvat": "11",
      "website_id": 1,
      "addresses": [
        {
          "id": 1,
          "customer_id": 1,
          "region": {
            "region_code": "CA",
            "region": "CA",
            "region_id": 0
          },
          "region_id": 0,
          "country_id": "NL",
          "street": ["Croeselaan 6"],
          "company": "",
          "telephone": "+31 30 295 5911",
          "fax": "",
          "postcode": "3521",
          "city": "Utrecht",
          "firstname": "John",
          "lastname": "Doe",
          "middlename": "",
          "prefix": "",
          "suffix": "",
          "default_shipping": true,
          "default_billing": true
        }
      ],
      "disable_auto_group_change": 0
    }

Utilizzo di curl in PHP

Dato un $token precedentemente inizializzato, ecco di seguito l’esempio in PHP equivalente alla chiamata precedente fatta con curl a linea di comando:

<?php
    /**
     * @return array
     * @throws Exception
     */
    function curlGet($endpoint, $token)
    {
      $curl = curl_init();
      curl_setopt_array($curl, [
          CURLOPT_URL => $endpoint,
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "GET",
          CURLOPT_HTTPHEADER => [
              "cache-control: no-cache",
              "authorization: Bearer " . $token,
          ],
      ]);

      $response = curl_exec($curl);
      $err = curl_error($curl);

      curl_close($curl);

      if ($err) {
          throw new Exception($err);
      } else {
          return json_decode($response, true);
      }
    }

    $response = curlGet(
      'http://hostname/index.php/rest/V1/customers/1',
      $token
    );

Integrazione tramite SOAP

In maniera equivalente a quanto visto in precedenza con REST, per poter accedere alle API SOAP occorre prima ottenere un token di autorizzazione; è possibile ottenerlo invocando uno specifico metodo SOAP che richiede le credenziali di un utente, come mostrato di seguito:

<?php
    function getAuthToken($hostname, $username, $password)
    {
      $wsdlUrl = "http://$hostname/soap/default?wsdl=1&services=integrationAdminTokenServiceV1";
      $soapClient = new SoapClient($wsdlUrl, ['soap_version' => SOAP_1_2]);
      $serviceArgs = ['username' => $username, 'password' => $password];
      $response = $soapClient->integrationAdminTokenServiceV1CreateAdminAccessToken($serviceArgs);
      return $response->result;
    }

Occorre notare che, a differenza di quanto avveniva in Magento 1, l’endpoint del WSDL non è più univoco ma generato in base ai servizi che si intende invocare.

Nell’esempio precedente ci interessa soltanto generare un token di autorizzazione, pertanto il servizio di riferimento è integrationAdminTokenServiceV1.

Utilizzeremo il token per accedere al catalogo prodotti; in questo caso il servizio di riferimento è catalogProductRepositoryV1 e infatti l’endpoint del WSDL cambia, come mostrato di seguito:

<?php
    $token = getAuthToken($hostname, $username, $password);
    $opts = [
      'http'=> [
          'header' => 'Authorization: Bearer ' . $token
      ]
    ];
    $wsdlUrl = "http://$hostname/soap/default?wsdl=1&services=catalogProductRepositoryV1";
    $serviceArgs = ["sku" => '24-MB01'];
    $context = stream_context_create($opts);

    $soapClient = new SoapClient($wsdlUrl, array(
      'soap_version' => SOAP_1_2,
      'stream_context' => $context
    ));

    $response = $soapClient->catalogProductRepositoryV1Get($serviceArgs);

L’elenco completo dei servizi disponibili è documentato qui: http://devdocs.magento.com/guides/v2.0/soap/bk-soap.html

Conclusioni

Come abbiamo visto, il maggior passo avanti nelle API di Magento 2 rispetto a Magento 1 è sicuramente l’equivalenza funzionale tra i protocolli REST e SOAP.

Questo permette di scegliere la modalità di integrazione preferita e di non essere limitati in funzione del protocollo utilizzato.

Gli esempi mostrati vogliono rappresentare un primo passo ma il consiglio è naturalmente quello di sperimentare e approfondire ulteriormente l’argomento consultando la documentazione ufficiale: http://devdocs.magento.com/

Crediti: la foto di copertina è di Billie Ward, rilasciata in accordo ad una licenza Creative Commons.

Alessandro Ronchi