This discussion is archived
4 Replies Latest reply: Oct 31, 2012 3:27 PM by J-Lig RSS

apex_web_service.make_rest_request: Passing parameters and the content type

trent Expert
Currently Being Moderated
Not sure if I am missing something, but should this API be setting the content type (to application/x-www-url-formencoded) when there are values present for the parameters p_parm_name and p_parm_value.

The example in the docs is to a yahoo API. I'm not sure about that particular one (see: http://docs.oracle.com/cd/E23903_01/doc/doc.41/e21676/apex_web_service.htm#BABEDJHJ), and I think it requires an appid (yahoo account), so i just went with the example here:

http://developer.yahoo.com/yql/guide/yql-code-examples.html#yql_php

If I run the following from a html file on my desktop it works:
<form method="POST" action="http://query.yahooapis.com/v1/public/yql">

<input type="hidden" name="q" value="select * from upcoming.events where location='San Francisco' and search_text='dance'"></input>
<input type="hidden" name="format" value="json"></input>
<input type="submit"></input>

</form>
That is, it returns a JSON result.

The raw HTTP data is as follows:
POST http://query.yahooapis.com/v1/public/yql HTTP/1.1
Host: query.yahooapis.com
Connection: keep-alive
Content-Length: 110
Cache-Control: max-age=0
Origin: null
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-AU,en;q=0.8,en-US;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

q=select+fromupcoming.events+where+location%3D%27San+Francisco%27+and+search_text%3D%27dance%27&format=json>

However, running the following returns nothing: (nothing, as in nothing that depends on the parameters passed in)
set serveroutput on

declare

l_c CLOB;

begin


  l_c := apex_web_service.make_rest_request(
    p_url => 'http://query.yahooapis.com/v1/public/yql',
    p_http_method => 'POST',
    p_parm_name => apex_util.string_to_table('q:format'),
    p_parm_value => apex_util.string_to_table('select * from upcoming.events where location=''San Francisco'' and search_text=''dance'':json'),
    p_proxy_override => 'http://192.168.1.3:8888');

  dbms_output.put_line(substr(l_c, 1, 4000));

end;
Raw HTTP data:
POST http://query.yahooapis.com/v1/public/yql HTTP/1.1
Host: query.yahooapis.com
Connection: Keep-Alive
Content-Length: 106
Connection: close

q=select+%2A+from+upcoming%2Eevents+where+location%3D'San+Francisco'+and+search_text%3D'dance'&format=json>

I do note a key difference is that content type isn't being set in the web service API.

This was just to test a public service. I do note that the above has slighty different request data (percentage encoding on some chars). However, I experienced the same behaviour on a procedure I had written (I can also provide this example test case if you like), which is where I first noticed the issue.

Using utl_http and setting the content type to application/x-www-url-formencoded, does resolve the issue. However, just thought i'd see the possibility of using the Web service API that is made available.

Is the example in the docs valid, or am I missing something obvious?

This is on ApEx 4.1 on the OTN Dev Days VM.

Thoughts?
  • 1. Re: apex_web_service.make_rest_request: Passing parameters and the content type
    Prabodh Guru
    Currently Being Moderated
    Hi trent,

    I too have had issues with this API , so moved forward with UTL_HTTP API.
    There is something amiss.

    If you change your code to the one below it works.
    SET SERVEROUT ON
    declare
     l_c CLOB;
     l_param varchar2(1000) ; 
    begin
     l_param := 'select * from upcoming.events where location=''San Francisco'' '||
            ' and search_text=''dance'''||'&'||'format=json'; 
     l_c := apex_web_service.make_rest_request(
        p_url => 'http://query.yahooapis.com/v1/public/yql?q='||
            utl_url.escape(l_param)
        ,p_http_method => 'POST'
        );
     
      dbms_output.put_line(substr(l_c, 1, 4000));
     
    end;
    /
    Note the use of UTL_URL.ESCAPE. The call does not work without it.
    I do not use a proxy, so that parameter does not feature in my snippet above.

    Cheers,

    PS: However, the below does not work. So, it appears that the p_parm_name and p_parm_value do not quite work.
    SET SERVEROUT ON;
    declare
     l_c CLOB;
     l_param varchar2(1000) ; 
    begin
     l_param := 'select * from upcoming.events where location=''San Francisco'' and search_text=''dance'''; 
     l_c := apex_web_service.make_rest_request(
        p_url => 'http://query.yahooapis.com/v1/public/yql'
        ,p_http_method => 'POST'
        ,p_parm_name => apex_util.string_to_table('q:format')
        ,p_parm_value => apex_util.string_to_table(utl_url.escape(l_param)||':json')
        );
     
      dbms_output.put_line(substr(l_c, 1, 4000));
     
    end;
    / 
    Edited by: Prabodh on Oct 13, 2012 2:04 PM
  • 2. Re: apex_web_service.make_rest_request: Passing parameters and the content type
    J-Lig Newbie
    Currently Being Moderated
    I had a similar issue:
    apex_web_service.make_rest_request wrapper missing header parms

    I endedup opening an SR for Oracle. I found out that headers (content-type) are set in global variables before making the apex_web_service.make_rest_request call.

    See http://docs.oracle.com/cd/E17556_01/doc/apirefs.40/e15519/apex_web_service.htm#autoId4 for a description of the headers and cookies.

    I endedup having to add the following to my code before apex_web_service.make_rest_request:

    apex_web_service.g_request_headers(1).name := 'Content-Type';
    apex_web_service.g_request_headers(1).value := 'application/xml';

    Once I did that, my service works. Odd. Not sure why they did it that way because their internal packages take header parameters, but the wrappers do it this way I guess.

    Hopefully this works for you!

    Jennifer
  • 3. Re: apex_web_service.make_rest_request: Passing parameters and the content type
    trent Expert
    Currently Being Moderated
    Oh great! had completely overlooked that section of the docs. Agree, seems odd.
  • 4. Re: apex_web_service.make_rest_request: Passing parameters and the content type
    J-Lig Newbie
    Currently Being Moderated
    Just figured out another nice little nugget...when I got that web service call working, I happened to run a different call and spent hours trying to figure out why it didn’t work anymore. Unfortunately this is not documented very well (at least anywhere I could find). What I figured out (eventually) is that when you set those headers, ALL service calls use them. When I ran my other call, it was trying to use those headers too. In case you have the same issues, here are some helpful tasks that took me forever to figure out:

    --To check the count of records in that g_request_headers table
    l_count := apex_web_service.g_request_headers.count;
    dbms_output.put_line('Count: '||l_count);

    --To check the name of record (by index) in that g_request_headers table
    --l_name := apex_web_service.g_request_headers(1).name;
    dbms_output.put_line('Name: '||l_name);

    --To check the value of record (by index) in that g_request_headers table
    --l_value := apex_web_service.g_request_headers(1).value;
    dbms_output.put_line('Value: '||l_value);

    --To delete the records from the g_request_headers table
    apex_web_service.g_request_headers.delete;

    Hopefully this will save you some time if you intend to make other service calls that dont require the same headers

    Jennifer

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points