Web service é uma solução utilizada para integração e comunicação entre diferentes aplicações. Por meio de um web service você pode disponibilizar funções ou mensagens para qualquer outra aplicação na internet ou em aplicações corporativas internamente.
Além disso, também é possível acessar (consumir) funções e mensagens de outros web services. A comunicação é realizada através do formato XML usando o protocolo HTTP. Através do XML, que é um formato universal, é possível que aplicações rodando em plataformas diferentes se comuniquem, simplesmente traduzindo seus dados para XML antes da comunicação. Já o protocolo HTTP é o mais utilizado na internet. É através desse protocolo que você pode navegar pelos sites usando seu navegador de preferência.
Neste contexto, o PHP nos fornece funções para trabalhar com web services de forma simples e fácil. Os dois principais tipos de comunicação com Web Service são SOAP e REST. Neste artigo iremos abordar como fazer a comunicação com esses dois tipos de Web Service.
SOAP
SOAP é um protocolo de comunicação baseado em XML que permite que aplicações troquem informações utilizando o protocolo HTTP. Mais especificamente, SOAP é um protocolo para acessar um Web Service. SOAP significa “Simple Object Access Protocol”. Por seguir um padrão W3C , é independente de plataforma e independente de linguagem de programação. É simples e extensível. Por trabalhar com o protocolo HTTP, que é o protocolo mais comum utilizado na internet, ele facilita a comunicação evitando que a transmissão seja bloqueada por um firewall ou proxy.
A descrição da interface de um web service SOAP é especificado em um documento XML chamado de WSDL (Web Services Description Language). O WSDL descreve o Web service e contém informações de como acessá-lo. Ele especifica a localização do serviço e quais são os seus métodos disponíveis. Portanto, caso esteja criando um web service que deseja disponibilizar para outros programas, será preciso criar o arquivo WSDL.
Existem diversas bibliotecas escritas em PHP para criação de web services SOAP. Porém, a melhor é a extensão SOAP nativa para PHP. Esta extensão requer outra extensão chamada libxml, que já vem instalada por padrão nas versões mais recentes do PHP. Portanto, para instalar a extensão SOAP no Linux basta compilar o php com a opção -enable-soap (compilando a partir do código fonte) ou para instalar a extensão SOAP no Ubuntu basta fazer sudo apt-get install php-soap. No Windows, a extensão SOAP já vem habilitada por padrão.
O PHP disponibiliza duas principais classes para trabalhar com SOAP:
SoapClient: classe cliente para acessar web services disponíveis por outras aplicações;
- SoapServer: para criar novos webservices e disponibilizá-los para outros aplicativos.
Neste artigo vamos criar uma pequena aplicação SOAP exemplificando a comunicação entre cliente e servidor. Como vimos anteriormente, nosso servidor SOAP precisa de um arquivo XML, chamado de WSDL, que especifica os métodos presentes em nosso web service. Porém, criar um arquivo WSDL manualmente é muito complexo. Infelizmente a classe nativa do PHP SoapServer não gera o arquivo WSDL automaticamente.
No PHP é possível operar no modo não WSDL, ou seja, sem a necessidade de existir um arquivo WSDL. Neste modo, o cliente de web service não conseguirá obter informações importantes, por exemplo o tipo de dados, formatação, etc. Assim, operar no modo não WSDL não é recomendado. Muitas plataformas como .NET, Java ou Ruby, necessitam de um WSDL para poderem funcionar.
No PHP, para gerar WSDL você tem disponível algumas ferramentas que auxiliam esse trabalho. Recomendo usar o IDE Zend Studio ou a classe Zend_Soap_AutoDiscover distribuída com o Zend Framework. Na sessão sobre Zend_Soap mais adiante neste artigo iremos demonstrar a utilização do Zend_Soap_AutoDiscover para geração do WSDL.
Vamos agora ao exemplo de uma aplicação SOAP simples. O exemplo apresentado na Listagem 1 temos o nosso servidor SOAP operando no modo não WSDL. Portanto, especificamos a opção “uri” e passamos “null” para o primeiro parâmetro do construtor da classe SoapServer. Depois disponibilizamos a classe SoapServerExemplo no web service contendo as funções “mensagem()” e “soma()”.
Listagem 1: Utilizando SOAP sem WSDL - Servidor
<?php
/* Criamos a instância do SoapServer.
* A opção uri indica o namespace do webservice no servidor.
* O primeiro parâmetro null indica que estamos trabalhando
* com um webservice no modo não WSDL.
*/
$options = array('uri' => 'http://127.0.0.1/soap/server/');
$server = new SoapServer(null, $options);
/*
* Informamos a classe em que o webservice irá se basear.
* Podemos usar também o método addFunction() para adicionar
* funções em nosso webservice.
*/
$server->setClass('SoapServerExemplo');
/*
* O método handle() processa a requisição SOAP e envia uma resposta
* para o cliente.
*/
$server->handle();
/*
* A classe SoapServerExemplo será disponibilizada em nosso
* webservice. Portanto temos disponíveis no webservice os métodos
* mensagem e soma.
*/
class SoapServerExemplo {
public function mensagem($nome)
{
return "Boas Vindas $nome !";
}
public function soma($a, $b)
{
return $a + $b;
}
}
Em seguida, na Listagem 2 temos o código responsável pelo cliente de nosso web service. Ele irá acessar as funções que o nosso servidor disponibiliza. Nesta listagem temos o script que irá consumir o web service criado anteriormente. Ele está trabalhando no modo não WSDL, portanto é necessário especificar os parâmetros “location” e “uri” e passar null para o primeiro parâmetro do construtor da classe SoapClient. Após isso já é possível utilizarmos as funções do web service: “mensagem()” que irá retornar uma string de “Boas Vindas” usando o parâmetro $nome e a função “soma” que retorna a soma dos dois parâmetros especificados na função.
Listagem 2: Utilizando SOAP sem WSDL - Cliente
<?php
/*
* Criamos a instância de nosso cliente de webservice.
* Especificamos a localização e o namespace do servidor de
* webservice.
* Passando null no primeiro parâmetro do construtor indicamos
* que o webservice irá trabalhar no modo não WSDL.
*/
$options = array(
'location' => 'http://127.0.0.1/soap/server/server.php',
'uri' => 'http://127.0.0.1/soap/server/'
);
$client = new SoapClient(null, $options);
/*
* No Objeto $client podemos usar os métodos da classe
* SoapServerExemplo disponível em nosso webservice.
*/
echo $client->mensagem('Douglas') . "<br />";
echo $client->soma(3, 5) . "<br />"
Ao acessar nosso primeiro web service obtemos o resultado apresentado na Figura 1.
Figura 1: Acesso inicial ao web service
Para enriquecer nosso conhecimento em relação a web services SOAP vamos agora demonstrar a comunicação com o site usando a API SOAP do PHP. Neste exemplo iremos construir um cliente de web service em php que conecta no amazon.com e nos traz o resultado de uma pesquisa de livros referente ao assunto PHP5.
Para podermos trabalhar com web services na Amazon é necessário antes fazer um cadastro no site deles e obter determinadas chaves que serão usadas em nosso web service como uma espécie de credencial. Para isso, acesse o site e faça o seu cadastro selecionando a opção Sign Up Now.
Após o cadastro, faça o login no site e copie as chaves necessárias para nosso web service. Para isso, primeiro clique em Account -> Security Credentials (ver Figura 2).
Figura 2: Recuperando as credenciais
Role a página até a sessão “Access Credentials” e copie as chaves “Access Key ID” e “Secret Access Key” (ver Figura 3).
Figura 3: Recuperando as credenciais Access Key ID e Secret Access Key
Após copiar as chaves necessárias já estamos prontos para criar nosso web service. O código necessário para esta atividade está apresentado na Listagem 3. Nesta listagem, temos um script que conecta no web service do site da amazon. Para autenticação é necessário especificar as chaves obtidas no site de web service da amazon conforme descrito anteriormente. Para consumir este web service é necessário configurar alguns cabeçalhos para a requisição SOAP: Timestamp, Acces Key ID e Signature. A signature é criada a partir de um algoritmo especificado na documentação sobre web service no site da amazon. Após isso, fazemos a chamada para a função “itemSearch”. Nos parâmetros da chamada especificamos o tipo de pesquisa que desejamos: Livros que contenham a palavra-chave “PHP5”. O retorno da função é um array de objetos contendo diversas informações sobre os itens encontrados pela pesquisa. Desses dados utilizamos somente alguns para serem exibidos na tela: Título do livro, autores, preço, imagem da capa, link para o site da amazon.
Listagem 3: Acessando o web service da Amazon
<?php
/* Copie aqui a Chave ACCESS KEY ID copiada do site da Amazon */
define('ACCESS_KEY_ID', 'xxxxxxxxxxxxxxxxxxxx');
/* Copie aqui a Chave SECRET ACCESS KEY copiada do site da Amazon */
define('SECRET_ACCESS_KEY', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
/* URL do web service da Amazon */
$wsdl_url = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl';
/* instância da classe SoapClient */
$client = new SoapClient($wsdl_url);
/*
Gera assinatura que deve ser enviada na requisição SOAP.
O algoritmo da assinatura é definido na especificação do
web service da Amazon
*/
$timestamp = gmdate("Y-m-d\TH:i:s\Z");
$string = 'ItemSearch'.$timestamp;
$signature = base64_encode(hash_hmac("sha256", $string, SECRET_ACCESS_KEY, true));
/*
Dados da Requisição: Iremos pesquisar livros que contenham
a palavra-chave PHP5
*/
$request = array(
'SearchIndex' => 'Books',
'ResponseGroup' => 'Large',
'Keywords' => 'PHP5');
$params = array(
'Request' => array($request)
);
/*
Cabeçalhos SOAP necessários para comunicação com amazon
*/
$soapheaders = array (
new soapheader("http://security.amazonaws.com/doc/2007-01-01/", "Signature", $signature),
new soapheader("http://security.amazonaws.com/doc/2007-01-01/", "Timestamp", $timestamp),
new soapheader("http://security.amazonaws.com/doc/2007-01-01/", "AWSAccessKeyId", ACCESS_KEY_ID)
);
/*
Setando os headers SOAP
*/
$client->__setSoapHeaders($soapheaders);
/*
Executando a pesquisa
*/
$livros = $client->__soapCall('itemSearch', array($params));
/*
Iterando nos itens encontrados referente a bus
...