Introduzione
Non ci siamo ancora occupati (ma ce ne occuperemo nei prossimi articoli) del classico front-end Web basato su pagine HTML, eppure ci immergiamo direttamente nel mondo dei Web Services. In un contesto in cui le tecnologie di integrazione costituiscono una necessità continua, abbiamo dato preferenza a tale aspetto e i Web Services sono, senza dubbio, la tecnologia di riferimento per l'integrazione di sistemi eterogenei. In luogo degli strumenti a riga di comando finora adoperati nei precedenti articoli, utilizzeremo RadRails come IDE di sviluppo. Andremo a creare due applicazioni, una per descrivere i passi necessari alla realizzazione di un Web Service da mettere a disposizione per essere fruito, l'altra per consumare un servizio disponibile. Non trascureremo la fase di test del servizio. Nell'effettuare queste operazioni cercheremo di toccare vari aspetti, tutti pragmaticamente interessanti per lo sviluppatore.
La prima applicazione
Iniziamo subito con la fase operativa. Apriamo RadRails (vedi Ruby II per i riferimenti) e creiamo il progetto Rails MokabyteWS. Con un classico File -> New -> Rails Project otteniamo il wizard per la creazione di un progetto Rails.
Inseriamo il nome del progetto (MokabyteWS nel nostro caso) e, lasciando le impostazioni di default "Generate Rails Application Skeleton" e "Create a Web Brick Server", clicchiamo su 'Finish'. La struttura del progetto, a meno di imprevedibili (!!!) errori, risulterà creata. Come selezionato con il check avremo a disposizione anche un server sul quale far girare le nostre applicazioni.
A questo punto utilizziamo la base dati utilizzata nell'articolo precedente (RubyIII) che contiene giusto la nostra tabella "countries". È nostra intenzione consentire la fruizione del contenuto della tabella via Web Services. Questo il contenuto dello script.
CREATE TABLE `countries` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(128) collate utf8_bin NOT NULL,
`continent` enum('Asia','Europe','Africa','Oceania','America') collate utf8_bin NOT NULL,
PRIMARY KEY (`id`)
)
Facciamoci puntare l'applicazione appena creata (vedi Ruby III parte per i dettagli sulla configurazione... questo solo se non leggi tutti gli articoli su Ruby...). In particolare ci riferiamo al file create.sql, presente nella cartella db, dove è contenuto lo script di creazione del database e al file database.yml dove ci sono i puntamenti veri e propri dei tre ambienti (sviluppo, test, produzione). Impostati i parametri delle connessioni al database la view 'data navigator' di RadRails ci consente di effettuare il browsing delle tabelle del database e, in un contesto in cui l'ORM utilizzato (ActiveRecord) usa un mapping implicito dei campi delle tabelle, questo risulta essere di fondamentale importanza (per non impazzire con i nomi dei campi!!!). A questo punto passiamo alla creazione del nostro controller. A differenza dell'articolo precedente non ricorriamo all'utilizzo di una "scaffold application" ma provvediamo puntualmente alla creazione di ogni componente dell'applicazione di cui abbiamo bisogno ricorrendo a qualche piccolo intervento in termini di codice mancante al completamento dell'applicazione (situazione abituale in contesto in cui è il cliente che decide i requisiti funzionali del progetto). Creiamo il nostro model facendo il mapping della tabella 'Countries'. Utilizzando RadRails abbiamo a disposizione, per far questo, una 'view Generators'
Scegliamo 'model' come primo parametro e impostiamo il nome della tabella come ulteriore parametro. Clicchiamo su 'Go' e attendiamo il generatore che faccia il proprio dovere. Abbiamo così ottenuto il file countries.rb che per il solo fatto di contenere una classe che estende ActiveRecord::Base mappa la tabella con il nome corripondente (di default Rails prende il nome come riferimento tra model e tabella occupandosi lui di fare il plurale nel nome delle tabelle) e una serie di file che costituiscono lo skeleton per le operazioni di test. È nostra intenzione mettere a disposizione un web service per fruire delle informazioni contenute nella tabella 'Countries'. Ricorriamo all'utilizzo del 'generator' con il parametro 'web_service'. Questo consentirà di generare il controller e la struttura necessaria alla fruizione del web service (con la medesima signature).
Notiamo che sono stati creati una serie di files tra i quali:
{rails-project-root}\app\apis\country_api.rb
{rails-project-root}\app\controller\country_controller.rb
Nel primo sono contenute le signature dei metodi, nel secondo le implementazioni dei servizi che saranno resi disponibili via web services. Concentriamoci sul metodo 'findallcountries'. Apriamo country_api.rb e specifichiamo la signature del nostro servizio. Attualmente il contenuto del file è il seguente skeleton:
class CountryApi < ActionWebService::API::Base api_method :find_all_countries end
Lo integriamo in modo tale che diventi:
class CountryApi < ActionWebService::API::Base
api_method :find_all_countries,
:returns => [[:string]]
end
E il controller:
class CountryController < ApplicationController
wsdl_service_name 'Country'
web_service_api CountryApi
web_service_scaffold :invoke
def find_all_countries
Country.find(:all).map { |country| country.name }
end
end
E il test:
def test_find_all_countries result = invoke :find_all_countries assert result[0].is_a?(String) end
Per lanciare il test dovremmo aggiungere il contenuto informativo della tabella 'countries' destinato ad essere utlizzato durante l'esecuzione. Quindi apriamo il file {rails-project-root}\test\fixtures\countries.yml e aggiungiamo la nostra nazione di interesse (operazione già effettuata in RubyIII). Facciamo lo start del server 'MokabyteWSServer', attendiamo che sia "started" e lanciamo il nostro test testlistall presente nel file countryapitest.rb. Per la gestione, utilizziamo gli strumenti messi a disposizione dall'IDE.
Per consumare il servizio:
endpoint = 'http://localhost:3000/country/service.wsdl' soap = SOAP::WSDLDriverFactory.new(endpoint).create_rpc_driver countries = soap.FindAllCountries
