Oracle ords: How to create put/post method with collection - json

I created a post method to receive the geolocation data of customers:
Post method
When I call the post method with the JSON:
{"customer": 1, "latitude":-21.13179, "longitude":-47.736782 }
my PL/SQL Script works.
Now I'd like to send a group of records but I don't know how to do it.
I created a PUT method to receive a collections of geolocations and I constructed a script just to parse the parameter:
Put method
When I call the put method with the JSON:
{
"items":[
{
"customer":1,
"latitude":-21.13179,
"longitude":-47.736782
},
{
"customer":1,
"latitude":-21.13179,
"longitude":-47.736782
}
]
}
PL/SQL code:
declare
l_values apex_json.t_values;
begin
apex_json.parse (
p_values => l_values,
p_source => :items );
end;
I received the message:
400 - Bad Request - Expected a value but got: START_ARRAY.
What I'm doing of wrong?
I want to create a post/put method to receive a collection.
Thanks for your help.

There is an example in OracleBase that shows a way to use 'JSON_Table' in 12c and 'JSON_Obect_t' pl/sql in 12Cr2. The JSON data is passed as a blob to the stored proc which then parses and updates/whatever. I have not tested it yet but it looks like a good approach to deal with collections which apparently cannot be handled by ORDS "out of the box". I had experimented with using the bulkload approach to load a temp table but it was for csv only and a bit tedious. Here's Jeff Smiths blog post on that
I have not tested this yet, I rebuilt my approach to send each entry individually but eventually I'll need to use this. I'll update this answer when I do with examples.

I am facing the same issue and the reason would be what is posted in the below URL.
https://community.oracle.com/thread/2182167?start=0&tstart=0
"In APEX Listener 1.1 the PL/SQL Hander will automatically convert JSON properties to implicit parameters. Note this will only work for simple JSON objects, arrays or nested object are not supported."
Basically - one can't pass collections/arrays. I'm not sure if this has changed now or if there are any plans to change this in the roadmap.

Related

What is the most elegant way to stream the results of an SQL query out as JSON?

Using the Play framework with Anorm, I would like to write a Controller method that simply returns the results of an SQL query as JSON. I don't want to bother converting to objects. Also, ideally this code should stream out the JSON as the SQL ResultSet is processed rather than processing the entire SQL result before returning anything to the client.
select colA colB from mytable
JSON Response
[{"colA": "ValueA", "colB": 33}, {"colA": "ValueA2", "colB": 34}, ...]
I would like to express this in Scala code as elegantly and concisely as possible, but the examples I'm finding seem to have a lot of boiler plate (redundant column name definitions). I'm surprised there isn't some kind of SqlResult to JsValue conversion in Play or Anorm already.
I realize you may need to define Writes[] or an Enumeratee implementation to achieve this, but once the conversion code is defined, I'd like the code for each method to be nearly as simple as this:
val columns = List("colA", "colB")
db.withConnection { implicit c =>
Ok(Json.toJson(SQL"select #$columns from mytable"))
}
I'm not clear on the best way to define column names just once and pass it to the SQL query as well as JSON conversion code. Maybe if I create some kind of implicit ColumnNames type, the JSON conversion code could access it in the previous example?
Or maybe define my own kind of SqlToJsonAction to achieve even simpler code and have common control over JSON responses?
def getJson = SqlToJsonAction(List("colA", "colB")) { columns =>
SQL"select #$columns from mytable"
}
The only related StackOverflow question I found was: Convert from MySQL query result or LIST to JSON, which didn't have helpful answers.
I'm a Java developer just learning Scala so I still have a lot to learn about the language, but I've read through the Anorm, Iteratee/Enumeratee, Writes, docs and numerous blogs on Anorm, and am having trouble figuring out how to setup the necessary helper code so that I can compose my JSON methods this way.
Also, I'm unclear on what approaches allow Streaming out the Response, and which will iterate the entire SQL ResultSet before responding with anything to the client. According to Anorm Streaming Results only methods such as fold/foldWhile/withResult and Iteratees stream. Are these the techniques I should use?
Bonus:
In some cases, I'll probably want to map a SQL column name to a different JSON field name. Is there a slick way to do this as well?
Something like this (no idea if this Scala syntax is possible):
def getJson = SqlToJsonAction("colA" -> "jsonColA", "colB", "colC" -> "jsonColC")) { columns =>
SQL"select #$columns from mytable"
}

Accessing data from API json response. Arrays? Laravel

I am trying to access the steamid data in a json response returned by an API, specifically the Steam API.
The responses look like this:
I've made it return json but why do I see array all over the place?
How would I access the steamid data? I'm getting a bit confused as I thought this would be json.
I'm using guzzle to get the data and converting it to json using the guzzle json() method:
Any help would be appreciated.
Thanks!
The API is indeed using JSON to send/receive , however JSON is just a string, so in order to use that data PHP must parse it, which is automatically handled by guzzle, so as soon as you get the data back it has automatically decoded the data into a usable format for yourself.
It does this using the json_encode() and json_decode() functions.
You'd be able to access the steamid with the following.
// Assuming $data is your response from the API.
$players = array_get($data, 'response.players', []);
foreach($players as $player)
{
$steamId = array_get($player, 'steamid', null);
}
Using the laravel helper array_get() function is a great way of ensuring you return a sane default if the data doesn't exist as well as eliminating the need to keep doing things like isset() to avoid errors about undefined indexes, etc. http://laravel.com/docs/5.1/helpers
Alternativly not using the laravel helpers you could use something similar to below, although I'd advise you add checks to avoid the aforementioned problems.
foreach($data['response']['players'] as $player)
{
$steamId = $player['steamid'];
}
If you didn't want guzzle to automatically decode the API's JSON I believe you should just be able to call the getBody() method to return the JSON string.
$json = $response->getBody();

ZF2: What's the easiest way to return a boolean json response?

In ZF1 it was pretty easy to send a json boolean response, for example, in the controller use:
return $this->_helper->json(true);
What's the easiest way to repeat this in ZF2?
I tried creating a new JsonModel with an array of variables. The only entry in the array was my boolean value (with a key of 0). This didn't work because the resolver was still off looking for a template.
I think I somehow need to return early?
EDIT:
I think this is a really important issue. For example, when the JQ Validation plugin uses a server-side validation method, it expects a JSON boolean response.
I managed to make my application JSON-ready by following 'alternate rendering and response strategies' section at the bottom of the Zend\View page, http://framework.zend.com/manual/2.0/en/modules/zend.view.quick-start.html. But this operates on the array that has been passed to the view, so the boolean true becomes json [true]
I tried the json view helper in various combinations, but couldn't get it to work.
Perhaps I need to create my own rendering and response strategies? That seems like overkill though...
Rob Allen has written an article about it:
Returning JSON from a ZF2 controller action
Also you can try this code to return every data without view rendering:
$response = $this->getResponse();
$response->setStatusCode(200);
$response->setContent('some data');
return $response;
The easiest way:
echo "true";
exit;
Though you may want to output some appropriate headers.
Arguably the correct way would be to add the JsonStrategy as viewstrategy and use a JsonModel, but I think it always returns an object (the json_encoded associative array of view variables passed to the JsonModel).

JavaScript front-end and Progress4GL back-end

I want to create an application with front-end HTML + JavaScript and back-end Progress4GL.
I found this documentation: http://communities.progress.com/pcom/docs/DOC-106147 (see Introducing AJAX and Introducing JSON). In the example described it is used GET method when requesting data:
xmlhttp.open("GET", "http://localhost/cgi-bin/cgiip.exe/WService=wsbroker1/getcustomersJSON_param.p?piCustNum="+ custval, true);
xmlhttp.send();
and on Progress4GL procedure for getting the param it is used get-value("piCustNum").
In my application I want to use POST method. So the request will be, for example:
xmlhttp.open("POST","http://localhost/cgi-bin/cgiip.exe/WService=wsbroker1/getcustomersJSON_param.p",true);
xmlhttp.send("piCustNum=" + custval);
But I don't know how to get the sent param on Progress side. Actually I want to send a stringify JSON.
Can anyone help me with this? Thanks!
If you want to POST JSON data to a webspeed program, check out WEB-CONTEXT:FORM-INPUT or if you post more than 32K, check out WEB-CONTEXT:FORM-LONG-INPUT.
Now... regarding reading the JSON data, it depends on your OpenEdge version. In 10.2B Progress started supporting JSON, however it is very limited, especially if you have little control of how the JSON gets created. Since you are the one creating the JSON data it may work for you. Version 11.1 has much better support JSON including a SAX streaming implementation.
We were on version 10.2 so I had to resort to using this C library to convert the JSON into a CSV file. If you have access to Python on your server it is very easy to convert to a CSV file
For the front-end I'd recommend you to use some library (like jQuery) to handle the ajax's request for you, instead of dealing with the complexity to work with different browsers, etc. You can use jQuery's functions like $.ajax, $.get or $.post to make your requests.
A post to a webspeed page could easily be done like this:
var data = {
tt_param: [ { id: 1, des: 'Description 1' } ]
}
var params = { data: JSON.stringify(data) }
$.post(
'http://<domain>/scripts/cgiip.exe/WService=<service>/ajax.p',
params,
function (data) {
alert('returned:' + data);
},
'text'
);
And the back-end would receive the JSON string using get-value('data'):
{src/web2/wrap-cgi.i}
def temp-table tt_param no-undo
field id as int
field des as char.
def var lc_param as longchar no-undo.
procedure output-header:
output-content-type("text/text").
end.
run output-header.
assign lc_param = get-value('data').
temp-table tt_param:read-json('longchar', lc_param).
find first tt_param no-error.
{&OUT} 'Cod: ' tt_param.id ', Des: ' tt_param.des.
It's a good place to start, hope it helps.
Cheers,
There is a library from Node for calling Progress Business Logic dynamically. I hope this would help.
node4progress

Wrapping JSON payload with key in EmberJS

Ok basically I am sending a POST request with some JSON payload in it to Codeigniter. I use RESTAdapater. JSON get sent there with no key, so I have no access to it.
Here is model:
App.Bookmark = DS.Model.extend({
title: DS.attr("string"),
url : DS.attr("string")
});
Here is controller:
App.BookmarksNewController = Ember.ObjectController.extend({
save: function(){
this.get("model.transaction").commit();
this.get("target").transitionTo("bookmarks");
}
});
In REST implementation in CI that I use standard way to access the post request is $this->input("key"). But when the above request is generated, only raw JSON data is sent. Therefore I don't seem to have a way to reference it in any way.
Take this example:
function post(){
$this->response(var_dump(file_get_contents("php://input")),200);
}
Gives me this output:
string(48) "{"bookmark":{"title":"sdffdfsd","url":"sdfsdf"}}"
what I would like to see is:
string(48) payload="{"bookmark":{"title":"sdffdfsd","url":"sdfsdf"}}"
Then is server I would be able to access this JSON with something like $this->post("payload").
So 1 of 2. Anyway to wrap the JSON payload with key? Or anyway to access raw JSON data in CI with no key available??
Ok figured it out myself (or rather read properly the examples).
When using Adam Whitney's fork of Phil Sturgeons REST controller for CodeIgniter the JSON payload will be available in $this->_post_args. And in the underlying implementation he uses my already mentioned file_get_contents("php://input").
EDIT: Same convention applies for other type of requests as well, for example DELETE request data will be available in $this->_delete_args. Or $this->_args is the "magic" place where all types of args can be found.