Follow Us on Twitter

Webservices in Application Express

Gepubliceerd in

Juni 2009 - Application Express (Apex) is een product van Oracle waarmee heel snel een webapplicatie gemaakt kan worden op een databaseschema. Naast de mogelijkheden om snel schermen te genereren op tabellen, bestaat er ook de mogelijkheid om schermen te baseren op webservices. Daarover gaat het in dit Whitebook.

Apex kan op een aantal manieren gebruik maken van webservices. Aan de ene kant biedt Oracle ingebouwde webservice support in Apex aan, maar aan de andere kant kan Apex ook gebruik maken van de mogelijkheden die UTL_HTTP in PL/SQL procedures biedt. Beide opties worden in dit Whitebook besproken.

Webservices

Wikipedia kent een definitie van de term webservice. Zij omschrijven het als volgt:“Een webservice kan omschreven worden als een interface van een applicatiecomponent die toegankelijk is via standaard webprotocollen en waarbij wordt gecommuniceerd via XML zonder menselijke tussenkomst.”

Een webservice maakt het mogelijk om informatie te benaderen via een afgesproken protocol, die door een derde partij is aangeboden, maar ook om informatie op te sturen naar een andere partij.
Binnen deze context wordt een aantal begrippen veelvuldig gebruikt.

  • UDDI (Universal Description, Discovery and Integration)
    • Dit is een soort wereldwijd telefoonboek van bedrijven die webservices aanbieden. Dit register is opgebouwd in XML en biedt bedrijven de mogelijkheid om elkaar te vinden via het internet.
  • WSDL (Web Services Definition Language)
    • Een WSDL is een XML-bestand bestaande uit een verzameling definities van webservices. Een aanroepende applicatie kan hieruit opmaken hoe de aangeboden webservices eruit zien en hoe deze aangeroepen moet worden.
  • SOAP (Simple Object Access Protocol)
    • SOAP is een breedgedragen protocol dat communicatie beschrijft tussen verschillende componenten. Onder andere Oracle, Sun, IBM, Microsoft en de Apache Software foundation steunen het initiatief. SOAP bevat een set regels die de codering en representatie van berichtenverkeer beschrijven. Ook bevat het een envelop die een raamwerk definieert voor wat in een bericht staat en hoe het verwerkt moet worden. SOAP wordt ook bij webservices gebruikt voor de uitwisseling van berichten.
  • Service Provider
    • De aanbieder van een webservice.
  • Service Requester
    • De aanvrager van informatie uit een webservice.
  • Service Broker
    • De plek waar de provider een webservice aanbiedt en waar de requester een webservice opzoekt.

 
Afbeelding 1 Schematisch overzicht van webservice verkeer

Webservices zijn te gebruiken om bijvoorbeeld RSS feeds, Google Maps, YouTube of PayPal te integreren in een eigen site, om op die manier een portal of Web2.0 site te maken.. In dit Whitebook zullen een aantal voorbeelden hiervan worden besproken.

Webservice aanmaken in Apex

Het toevoegen van een webservice aan een Apex applicatie kan op een aantal manieren. De eerste manier maakt gebruik van een wizard. Hiervoor zijn een UDDI referentie of het URL van een WSDL nodig.

Om een webservice reference aan te maken in Apex, navigeer je naar ‘Shared Components’ en vervolgens naar ‘Web Service References’. Hier klik je op de knop ‘Create’ om een nieuwe reference aan te maken.

Als eerste vraagt Apex of er gebruik gemaakt moet worden van een UDDI registry om de juist WSDL op te zoeken. Als het URL van de WSDL al bekend is, is dat niet nodig.

Op de volgende pagina kan de WSDL locatie worden opgegeven en eventueel een username en password als de webservice dat vereist. Als voorbeeld vullen we de WSDL locatie in van de Google Search Api, waarmee de Google zoekfunctionaliteit kan worden aangeroepen. Het URL hiervan is:

http://api.google.com/GoogleSearch.wsdl

Apex leest vervolgens de WSDL uit en toont op de volgende wizardpagina een overzicht van de webservice met z’n naam, het endpoint van de de SOAP envelope en de Soap Style. Dit kan Apex dus doen, omdat webservices volledig zijn opgebouwd uit standaarden. Apex weet altijd wat het waar kan verwachten.

Verder wordt een overzicht gegeven van de beschikbare operations in de webservice.

 
Afbeelding 2 Webservice details

Hiermee heeft de wizard genoeg informatie om de webservice reference aan te maken. In het laatste scherm kan vervolgens gekozen worden om direct een Form of Form and Report pagina aan te maken op de webservice.

Handmatig webservice aanmaken

In het tweede voorbeeld wordt gebruik gemaakt van een handmatig aangemaakte webservice reference. Dit kan noodzakelijk zijn als er bijvoorbeeld geen WSDL bekend is. De gebruiker zal dan fysiek contact op moeten nemen met de aanbieder van de webservice om te weten wat er nodig is om de webservice aan te roepen.

In dit voorbeeld roepen we een webservice aan bij de videowebsite YouTube, welke een lijst teruggeeft van de favoriete video’s van een opgegeven gebruiker.

De URL van de te gebruiken webservice is:

http://www.youtube.com/api2_xmlrpc

De optie om handmatig een webservice reference aan te maken is een beetje verstopt in de interface van Apex. Eerst moet er genavigeerd worden naar hetzelfde scherm als bij het aanmaken van een webservice via de wizard uit de vorige paragraaf. Op het venster waar de WSDL referentie kan worden ingevoerd is in het menu aan de rechterkant een link te zien met de tekst ‘Create Web Service Reference Manually’.

Na het aanroepen van de link verschijnt een nieuw scherm waarin een aantal zaken verplicht moeten worden ingevuld.

 
Afbeelding 3 Handmatig aanmaken webservice

De verplichte velden die ingevoerd moeten worden zijn: een zelf te kiezen naam voor de webservice, de URL van de aan te roepen webservice en een SOAP envelope die de structuur van de webservice beschrijft.
Deze envelope kan zelf worden gemaakt als alle informatie beschikbaar is, maar makkelijker is het om gebruik te maken van een programma als SoapUI.

Voor dit voorbeeld is de onderstaande SOAP envelope noodzakelijk. In de regel onder dev_id is een code te zien die YouTube gebruikt om ontwikkelaars te identificeren. Dit Id moet aangevraagd worden bij YouTube door te registreren als ontwikkelaar.

De regel onder user bevat een referentie naar de variabele member_id die we gaan vullen vanuit een Apex pagina.

<?xml version='1.0'?> <methodCall> 
<methodName>youtube.users.list_favorite_videos</methodName>
<params>
<param><value><struct>
<member>
<name>dev_id</name>
<value><string>7S3ToS2-l_M</string></value>
</member>
<member>
<name>user</name>
<value><string>#P7_MEMBER_ID#</string></value>
</member>
</struct></value></param>
</params> </methodCall>

Deze SOAP envelope kan vervolgens getest worden in de ingebouwde testpagina van Apex (Shared Components -> Logic -> Web Service References). Als het zoekpaneel bovenin de pagina is ingesteld op View:Details, is een kolom Test te zien met een stoplichticoon om naar de testpagina te gaan.

In de pagina is de gebruikte SOAP envelope te zien. Om deze nu te kunnen testen dient de variabele #P7_MEMBER_ID voor de test vervangen te worden door een op YouTube geregistreerde gebruikersnaam.

Als response geeft de webservice een XML-bericht met daarin informatie over de favoriete video’s van een bepaalde geregistreerde YouTube gebruiker. Deze informatie kan dan vervolgens getoond worden door een Apex pagina.

<?xml version='1.0'?> 
<methodResponse>
<params>
<param>
<value><string>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;ut_response status="ok"&gt;&lt;video_list&gt;&lt;total&gt;10&lt;/total&gt;&lt;video&gt;&lt;author&gt;velorex350&lt;/author&gt;&lt;id&gt;6FQXnbTZGgs&lt;/id&gt;&lt;title&gt;Suzanne de Jong [Veronica Maart Automaand trailer]&lt;/title&gt;&lt;length_seconds&gt;194&lt;/length_seconds&gt;&lt;rating_avg&gt;4.71&lt;/rating_avg&gt;&lt;rating_count&gt;34&lt;/rating_count&gt;&lt;description&gt;Veronica Maart Automaand starring Suzanne de Jong &amp; Robert Doornbos feat. Anton de Leeuw directed by Ralph J Russell&lt;/description&gt;&lt;view_count&gt;30363&lt;/view_count><upload_time&gt;1172881463&lt;/upload_time&gt;&lt;comment_count&gt;14&lt;/comment_count&gt;&lt;tags&gt;Suzanne de Jong Veronica Maart Automaand Robert Doornbos BMW M5&lt;/tags&gt;&lt;url&gt;http://www.youtube.com/watch?v=6FQXnbTZGgs&lt;/url&gt;&lt;thumbnail_url&gt;http://i3.ytimg.com/vi/6FQXnbTZGgs/default.jpg&lt;/thumbnail_url&gt;&lt;embed_status&gt;ok&lt;/embed_status&gt;&lt;allow_ratings&gt;yes&lt;/allow_ratings&gt;&lt;/video&gt;&lt;/video_list&gt;&lt;/ut_response&gt;
</string>
</value>
</param>
</params>
</methodResponse>

Integreren webservice

Als de webservice goed functioneert volgens verwachtingen, kan deze geïntegreerd worden in de Apex applicatie. De opgehaalde informatie wordt eerst opgeslagen in een collection, zodat de applicatie er makkelijk bij kan. Deze collection is in de pagina op afbeelding 3 al gedefinieerd. Standaard wordt de collection opgeslagen in een clob. Om deze te kunnen gebruiken wordt eerst de clob omgezet naar een leesbaar XML formaat, zoals te zien is in onderstaande code.

declare 
l_clob clob;
l_xml xmltype;
l_val clob;
begin
for c1 in (select clob001
from apex_collections
where collection_name = 'YOUTUBE_FAVOURITE_VIDEOS' )
loop
l_clob := c1.clob001;
exit;
end loop;
l_xml := xmltype.createxml(l_clob);
l_val := dbms_xmlgen.convert(l_xml.extract('/methodResponse/params/param/value/string/text()').getclobval(),1);
apex_collection.update_member_attribute(
p_collection_name => 'YOUTUBE_FAVOURITE_VIDEOS',
p_seq => '1',
p_clob_number => '1',
p_clob_value => l_val );
end;

In de Region Source van de pagina wordt de standaard functionaliteit gebruikt die Oracle aanbiedt om XML te lezen. De onderstaande code haalt de gewenste gegevens op uit de collection.

select extractValue(value(t),'/*/id') "id" 
, extractValue(value(t),'/*/title') "title"
, extractValue(value(t),'/*/author') "author"
, extractValue(value(t),'/*/length_seconds') "length_seconds"
, extractValue(value(t),'/*/rating_avg') "rating_avg"
, extractValue(value(t),'/*/rating_count') "rating_count"
, extractValue(value(t),'/*/description') "description"
, extractValue(value(t),'/*/view_count') "view_count"
, to_char(new_time(to_date('01011970','ddmmyyyy')+1/24/60/60 * extractValue(value(t),'/*/upload_time'),'GMT','EDT'),'dd-mon-yyyy hh24:mi:ss') "upload_time"
, extractValue(value(t),'/*/comment_count') "comment_count" , extractValue(value(t),'/*/tags') "tags"
, '<a href="'||extractValue(value(t),'/*/url')||'"><img _fcksavedurl=""'||extractValue(value(t),'/*/url')||'"><img" src="'||extractValue(value(t),'/*/thumbnail_url')||'" /></a>' "View"
, extractValue(value(t),'/*/embed_status') "embed_status"
from wwv_flow_collections c, table(xmlsequence(extract(xmltype.createxml(c.clob001),'//video_list/video'))) t
where c.collection_name = 'YOUTUBE_FAVOURITE_VIDEOS'

Uiteraard is er nog meer nodig om een compleet werkende pagina te krijgen, maar dit zijn de meest interessante stukken met betrekking op webservices.

Als de pagina uiteindelijk wordt geopend, ziet het stuk dat is opgehaald met de webservice eruit als in onderstaande afbeelding.


Afbeelding 4 Youtube webservice

Webservice via UTL_HTTP

Als derde voorbeeld gaan we in op het gebruik van UTL_HTTP bij het aanroepen van een webservice. In dit geval maken we gebruik van een webservice van Google Maps die een adres als invoer accepteert en een geografische locatie als uitvoer terugstuurt.

UTL_HTTP is een built-in package van Oracle, welke de afhandeling regelt van http requests met de database. Heel simpel gezegd: het is de poort van de database naar het wereldwijde web.

Deze package kan ook worden ingezet om webservices aan te roepen.

In het voorbeeld wordt een page gemaakt met daarop een PL/SQL region om de aanroep naar de webservice af te handelen.
In het vetgedrukte stuk in onderstaand codefragment, wordt de aanroep naar de webservice opgebouwd en uitgevoerd. In dit voorbeeld worden een aantal variabelen uit de url gevuld in een stuk PL/SQL code welke is opgenomen in de eerder genoemde region. Aan het url worden het adres, het outputtype (in dit geval csv) en een api_key (vergelijkbaar met het dev_id uit het YouTube voorbeeld) toegevoegd.
Met behulp van utl_http.request wordt nu een aanroep gedaan naar de opgebouwde url, met eventueel een proxy server indien de situatie dit vereist.

declare 
l_address varchar2(4000);
l_url varchar2(32000);
l_response varchar2(3200);
begin
l_address := :P1_STREET||','||:P1_CITY;
if :P1_STATE is not null then
l_address := l_address||','||:P1_STATE;
end if;
if :P1_COUNTRY is not null then
l_address := l_address||','||:P1_COUNTRY;
end if;
l_address := replace(l_address,' ','+');
l_url := 'http://maps.google.com/maps/geo?q='||l_address||'&'||'output=csv'||'&'||'key='||:API_KEY;
l_response := utl_http.request(l_url, APEX_APPLICATION.G_PROXY_SERVER);
:P1_RESPONSE := l_response;
:P1_LOCATION := substr(l_response,instr(l_response,',',1,2)+1);
end;

De webservice van Google Maps geeft hierna de coördinaten terug waar het aangevraagde adres zich bevindt.

Conclusie

Het integreren van een webservice in Apex is optie die veel mogelijkheden biedt. Door gebruik te maken van webservices, is het mogelijk om Apex in te zetten in de meest complexe Web 2.0 omgevingen.

Standaard biedt Apex de mogelijkheid om automatisch code te genereren voor het gebruik van webservices in een applicatie. Waar dit niet voldoet is goed gebruik te maken van alternatieven, zoals bijvoorbeeld het handmatig aanmaken van de webserviceaanroep of UTL_HTTP. Hiermee is het gebruik van webservices in Apex een krachtige en flexibele optie geworden.

Bronnen

Waardering:
 

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.