Acessando um Web Service utilizando a biblioteca IndySOAP no Kylix 3 Open Edition (Kylix3 OE)
O objetivo deste tutorial é ajudar os desenvolvedores a
utilizar o Kylix Open
Edition com a biblioteca IndySOAP.
Este tutorial faz parte da documentação do projeto GOPE
e visa auxiliar os desenvolvedores do projeto a entenderem como
funciona o acesso aos Web Services utilizando o IndySOAP. O tutorial
assume que o desenvolvedor já tem o ambiente funcionando.
Se você achar algum erro neste tutorial, por favor email para
editorweb @ jsk.com.br.
Introdução - Entendendo os Web Services
Simple Object Access Protocol (SOAP) é a base sobre qual Web
Services (WS) é construído. É uma um protocolo
baseado em XML usado para que os Web Services se comuniquem. O Delphi e
o Kylix fazem este acesso a este protocolo utilizando três
bibliotecas: a biblioteca nativa que vem com o Delphi/Kylix Enterprise,
a biblioteca paga Asta IO e a biblioteca open source IndySOAP.
A mecânica de utilização do Web Services
é simples. Dada uma URL onde se localiza um WS, o usuário
faz acesso a um dos método disponíveis através do
envio de uma mensagem SOAP. O WS envia então um outro pacote
SOAP contendo a resposta a requisição ou uma mensagem de
erro (SOAPFault).
Um exemplo simples de uma chamada SOAP é através do
javascript disponível em browsers baseados no Mozilla. Iremos
utilizar o serviço babelfish que traduz uma palavra ou frase de
uma língua para outra:
var babelFishCall = new
SOAPCall();
babelFishCall.transportURI = "http://services.xmethods.net:80/perl/soaplite.cgi";
// SOAP params
var param1 = new SOAPParameter();
param1.value = "pt_en";
param1.name = "translationmode";
var param2 = new SOAPParameter();
param2.value = "Liberdade";
param2.name = "sourcedate";
// combine the 2 params into an array
var myParamArray = [param1,param2];
babelFishCall.encode(0, "BabelFish",
"urn:xmethodsBabelFish",
0, null, myParamArray.length, myParamArray);
var translation = babelFishCall.invoke();
if(translation.fault){
// error returned from the web service
alert(translation.fault.faultString);
} else {
// we expect only one return SOAPParameter - the
translated
string.
var response = new Array();
response = translation.getParameters(false, {});
alert("Tradução: " + response[0].value);
}
Eu sempre gosto de dar este exemplo pois ele é fácil de
ser testado e o resultado é imediato. Repare nos itens em azul
que são os parâmetros que devem ser passados. O primeiro
é o endereço do WS. Em seguida são criados dois
objetos SOAPParameter() que contém o translationmode (que
contém a linguagem de origem [pt] e a de destino [en]) e
qual o texto que deve ser traduzido.
O passo final é chamar o WS utilizando o método BabelFish passando os parâmetros definidos. O WS retornará um pacote SOAP com algum erro (caso você tenha passado um parâmetro errado) ou então você terá o texto traduzido.
Para que você consiga testar (não esqueça:
somente no Mozilla / Firebird / Netscape 7):
Tudo muito bonito, muito certinho, mas vamos cair na real:
1) como é que eu sei quais os métodos que existem no
WS ? Será que existe um método que me dá o grau de
certeza da tradução, ou então uma lista de
sinônimos próximos ?
2) como é que eu sei quais os parâmetros que eu tenho passar para cada método ?
3) E finalmente, como eu sei qual será o retorno que o WS me
dará ?
Para me informar de todos estes detalhes, existe então o
padrão WSDL
- Web
Service Description Language também
baseado em XML. Nele, é possível informar quais os
métodos que podem ser chamados, quais os parâmetros que
devem ser passados, explicar como cada método funciona e quais
os pré-requisitos para que ele seja executado. Veja como
é na prática o WSDL do nosso exemplo do BabelFish aqui.
Como executar o SOAP utilizando a biblioteca IndySOAP
Vamos agora fazer o mesmo teste no IndySOAP. A mecânica
é a seguinte:
1) Transformar o WSDL em uma interface Pascal / Kylix
2) Criar um form que acesse um serviço SOAP
3) Testar !
O primeiro passo é utilizar o utilitário IdSoapTools
que fica localizado no diretório Tools do IndySoap. Este
utilitário tem dois objetivos primários:
- O gerador do arquivo ITI - este arquivo é utilizado pelo IndySoap para mapear os métodos do WS em tempo de runtime necesários para que o IndySOAP funcione.
- O conversor WSDL para PAS que converte uma
definição WSDL em um arquivo que representa a Interface
Pascal do WS.
Quando se está escrevendo um WS, ou seja, o serviço em
si, você escreve a interface em Pascal e o arquivo ITI e o WSDL
são gerados automaticamente pela biblioteca.
Quando se está consumindo um WS, parte-se do WSDL publicado
pelo autor do WS e deve-se gerar a interface Pascal para que possamos
interagir com os serviços através do Delphi / Kylix.
Assim, para transformar o WSDL em Pascal, deve-se utilizar o
IdSoapTools.
O IdSoapTools se baseia em um arquivo com extensão IdSoapCfg. No nosso exemplo do BabelFish, a configuração deve ser a seguinte:
[Project]
/home/josir/dlib/indy/indysoap/Tutorials/babelfish
[Source]
BabelFish.pas
[Output]
BinOutput=BabelFish.iti
[WSDL]
Source=http://www.xmethods.net/sd/2001/BabelFishService.wsdl
Pascal=BabelFish.pas
Factory=0
PrependTypes=1
MakeITIRes=0
O IndySOAP mapeia os WS de três formas: através de um
resource file, através de um formato proprietário chamado
ITI e através de um formato XML. Inicialmente, optei pelo
formato .res pois ele é aclopado diretamente no
executável através da diretiva {$R *.res} Entretanto, o
arquivo .res não funcionou com o Kylix: sempre que tentava
compilar, dava erro de 'Bad Resource Format'. Assim, optei pelo formato
ITI.
1) Crie um arquivo texto chamdo Babelfish.IdSoapCfg baseado
nos
dados acima.
2) Compile o IdSoapTools e execute.
3) Abra o arquivo criado através de File / Open
4) Dê um Execute.
O utilitário irá gerar dois arquivos o BabelFish.pas e
o BabelFish.iti. De posse destes arquivos vamos agora criar um novo
projeto a partir do Kylix.
5) Dê um File / New / Application
6) Adicione o BabelFish.pas ao projeto
7) Inclua a unit BabelFish no uses do Form.
8) Ainda no form, jogue um TEdit e um TButton.
9) Vá agora na palete do IndySOAP e jogue um TIdSoapClientHTTP
no form e altere o Name para SoapHTTP.
10) No botão, crie o
evento do OnClick com o código abaixo:
var Resposta: String;
begin
Resposta := (SoapHTTP as
IBabelFish).BabelFish('pt_en',Edit1.Text);
ShowMessage( Resposta );
end;
11) Agora a parte mais importante: vamos preencher as propriedades do
SoapHTTP.
- ITIFileName: coloque o path do arquivo
Babelfish.iti criado.
- ITIResourceName = BabelFish
- SoapURL = o endereço que efetivamente
trata
a mensagem SOAP que você enviará.
12) Compile e faça bom proveito!!
Conclusão
Pode-se perceber que a utilização da biblioteca
não é trivial mas também não é
nenhum bicho de sete cabeças. Como não coloquei nenhum
beta-tester para executar o tutorial, é possível que eu
tenha pulado algum passo. Assim se alguém descobrir algum erro
ou se quiser sugerir ajustes enviem email para josir @ jsk.com.br.
O projeto babelfish.tgz
contém o programa pronto mas o ideal é que você
monte o passo a passo para um melhor entendimento.
Este artigo se baseou na documentação do IndySOAP e no
artigo do devedge.netscape.com que fala sobre o serviço
BabelFish.
Atualizado em 24/10/2004


