JSK Home Page

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:

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