Contextualizando
O que é HTTP?
Hypertext Transfer Protocol (HTTP, ou Protocolo de Transferência de Hipertexto) é um método que faz a comunicação entre os clientes e servidores através de request (requisição) e response (resposta). Arquivos de hipertexto são arquivos que podem ser manipulados via HTML, mas o protocolo HTTP não se restringe apenas a arquivos de hipertexto.
Um cliente (navegador do usuário) envia uma requisição para o servidor, que roda a aplicação para processar a resposta. Ao término do processamento o servidor retorna uma resposta para o navegador.
O que é API REST?
Application Programming Interface (API, ou Interface de Programação de Aplicações) é o conjunto de instruções e padrões de programação que servem para fornecer dados e informações relevantes de uma determinada aplicação. Uma API possui uma interface de um endpoint que fica exposto publicamente para receber requisições e responde-las com mensagens programáticas através de respostas.
Os endpoints são aspectos importantes para a interação com as APIs, normalmente os endpoints são URIs via requisições HTTPs.
Representational State Transfer (REST, ou Transferência Representacional de Estado) é um conjunto de restrições utilizadas para que as requisições HTTP atendam as diretrizes definidas na arquitetura. Os serviços que estão em conformidade com o estilo arquitetural REST, são denominados RESTfull.
- POST: método da aplicação para criar dados no servidor;
- GET: método da aplicação para buscar dados no servidor;
- DELETE: método da aplicação para excluir dados no servidor;
- PUT: método da aplicação para atualizar dados no servidor.
Magento 2 e APIs
O Magento 2 utiliza reflexão para criar classes automaticamente e definir dados que serão enviados para uma instância da classe PHP chamada no método de serviço da API.
Para ter acesso as informações dos parâmetros que o método de serviço espera e o tipo do retorno do método, é utilizado a anotação do PHP (docblock).
Código para criar API REST
webapi.xml
Para a criação de APIs personalizadas é preciso definir alguns elementos no arquivo webapi.xml
, seguindo a estruturas de pastas \{Vendor}\{Module}\etc\{area}\webapi.xml.
<?xml version="1.0" ?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route method="{METHOD}" url="/V1/{endpoint}/:{paramName}" secure="{true/false}">
<service class="{Vendor}\{Module}\Api\{ApiName}Interface" method="{methodName}"/>
<resources>
<resource ref="{resource_reference}"/>
</resources>
<data>
<parameter name="{parameterName}" force="{true/false}">{value}</parameter>
</data>
</route>
</routes>
O nó <routes>
é o elemento que define a localização do arquivo de esquema XML para a API. O nó <route>
é filho do nó <routes>
e obrigatório para definir qual o método e o endpoint serão utilizados na API.
Atributos do nó 'route'
Atributo | Descrição | Obrigatório |
---|---|---|
method | Tipo do método HTTP (GET, POST, PUT e DELETE). | true |
url | A URL para o endpoint exposto da API. Deve iniciar com "/V{integer}/" para indicar o número da versão. | true |
secure | Indica se a rota da API está acessível apenas para protocolo HTTPS. | false |
O nó <service>
é filho do nó <route>
e obrigatório para definir a implementação da API e o método que será chamado.
Atributos do nó 'service'
Atributo | Descrição | Obrigatório |
---|---|---|
class | Especifica a localização da interface responsável para a implementação da API. | true |
method | Especifica o nome do método que será executado na interface. | true |
O nó <resources>
é filho do nó <route>
e obrigatório para definir a qual seção(ões) do(s) recurso(s) ACL a API tem acesso. Não possui nenhum atributo.
O nó <resource>
é filho do nó <resources>
e obrigatório para definir a qual seção do recurso ACL a API tem acesso. Possui apenas o atributo ref
que pode possuir os seguintes valores:
-
anonymous
: Permite que a API seja pública e podendo ser acessada por visitantes; -
self
: Para consultar a API é necessário a autenticação com oauth, token, oauth2; -
{Vendor}_{Module}::{acl_path}
: Referenciar seção a um recurso ACL para fornecer permissões das configurações.
O nó <data>
é filho do nó <route>
e opcional para definir os parâmetros da API através de seus nós filhos. Não possui nenhum atributo.
O nó <parameter>
é filho do nó <data>
e obrigatório caso o nó <data>
for especificado. para definir a qual seção do recurso ACL a API tem acesso. Possui apenas o atributo ref
que pode possuir os seguintes valores:
Atributos do nó 'parameter'
Atributo | Descrição | Obrigatório |
---|---|---|
name | Nome do parâmetro. | true |
force | Este atributo garante que em uma rota específica da API, o valor do parâmetro será forçado a usar o valor passado no nó. | false |
Interface
Todos os métodos expostos pela API devem declarar na interface a tag @param type $paramName
para indicar o tipo(s) do(s) parâmetro(s) esperado(s) e o nome do parâmetro esperado pela API e a tag @return
para indicar o tipo do retorno do método na API.
É possível acessar os parâmetros passados na URL através dos métodos que foram vinculados a API, desde que eles estejam com o mesmo nome em ambos os lugares e que na declaração do método o parâmetro esteja declarado certo (com o docblock correto).
É possível acessar o body enviado para a API como se fosse um parâmetro do método declarado, desde que eles estejam com o mesmo nome em ambos os lugares e que na declaração do método o parâmetro esteja declarado certo (com o docblock correto).
Body:
{
"{bodyName}": {
"{attr}": "{value}",
"{attr}": "{value}",
...
}
}
Interface:
<?php
namespace {Vendor}\{Module}\Api;
interface {ApiName}Interface
{
/**
* @param {type} $paramName
* @param {type} $bodyName
* @return {returnType}
*/
public function {methodName}({type} $paramName, {type} $bodyName): {returnType};
}
Serviço
Após a criação da interface da API é necessário a sobrescrição através do arquivo di.xml
, para que o arquivo fique devidamente implementado e possa descrever em como os métodos serão executados.
Preference:
<preference for="{Vendor}\{Module}\Api\{ApiName}Interface" type="{Vendor}\{Module}\Service\{ApiName}" />
Service:
<?php
namespace {Vendor}\{Module}\Service;
use {Vendor}\{Module}\Api\{ApiName}Interface;
class {ApiName} implements {ApiName}Interface
{
/**
* @param {type} $paramName
* @param {type} $bodyName
* @return {returnType}
*/
public function {methodName}(type $paramName): {returnType}
{
// Code implementation
}
}
Finalizando
Valores entre chaves ({test}
) devem ser alterados na implementação do código.
Habilitando as alterações
Apague os arquivos que são gerados na compilação do Magento e execute o comando PHP para gerar a configuração das injeções de dependência e todas as classes ausentes que precisam ser geradas (proxys, interceptors, etc).
rm -rf var/generation/
rm -rf generated/
php bin/magento setup:di:compile
Diretórios e Arquivos
Segue a a lista de diretórios e arquivos que devem ser criados.
- app/
- code/
- {Vendor}/
- {Module}/
- Api/
- {ApiName}Interface.php
- etc/
- di.xml
- module.xml
- Service/
- {ApiName}.php
- registration.php
- composer.json