1. Necmettin Urkmez
  2. SnapObjects
  3. Wednesday, 27 November 2019 14:18 PM UTC


I have seen some code in "orderdemo" project.

---------------------
PB client side code that consumes web api....
--------------------------
String ls_url
String ls_response
String ls_json
JsonPackage lnv_package
Int li_return

lnv_package = Create JsonPackage
lnv_package.SetValueByDataWindow("order", adw_order, true)
lnv_package.SetValueByDataWindow("orderitems", adw_orderitems, true)

ls_url = gn_RESTClient.of_get_url("WOrderNew", "UeSave")
If gn_RESTClient.of_post(ls_url, lnv_package) > 0 Then
li_return = 1
Else
li_return = -1
End If

Destroy lnv_package

Return li_return
----------------------------------------------------------------------------

------------------
Web api side
------------------

// POST api/WOrderNew/UeSave
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public ActionResult UeSave(IDataUnpacker dataUnpacker)
{
// Declare and initialize local .NET DataStore variables
// By getting the Packaged DataStores
IDataStore order = dataUnpacker.GetDataStore("order");
IDataStore orderItems = dataUnpacker.GetDataStore("orderitems");

// Check if the modification was successful
if (_service.UeSave(order, orderItems))
{
// Return Status Code 200
return Ok();
}
else
{
// Return a Status Code 500 for Internal Server Error
return StatusCode(StatusCodes.Status500InternalServerError);
}
}

My question is that,

Is it possible to use JSONPackage object non-PB clients? Or how can I consume UeSave API any other type client such as java script or mobile client?


Regards and Thanks

Michael Kramer Accepted Answer Pending Moderation
  1. Wednesday, 27 November 2019 15:32 PM UTC
  2. SnapObjects
  3. # 1

Hi, What any client receives is a JSON formatted text (aka. JSON document) so any client capable of reading JSON formatted text can consume this web API.

It just so happens, that PowerScript's JSONPackage - and the DataWindow engine - know who to interpret such JSON formatted text that it requires very little additional code to have such web API as back-end and DataWindows in the front-end.

When I learned the JSON syntax of SnapObjects I used the Postman tool to send HTTP requests and read/interpret the responses. I still have Postman as my primary testing tool for web-APIs.

HTH /Michael

Comment
  1. Necmettin Urkmez
  2. Wednesday, 27 November 2019 19:39 PM UTC
Thanks for your answer. But It is not the one that I am looking for. You can try my question in orderdemo that was provided by Appeon.

There is no problem with Datastore object, if you only need to retrieve data. Since It can export plain text JSON(Datastore.ExportJson()).

But when it comes to tracsactional operation such as update, create etc,

Power Builder Client sent a json as follows below. That complex message can be mapped to Datawindow by Dataunpacker object.

My question is that how Datastore can process other type client message

those send plain JSON text like Angular or native mobile client. Otherwise I have to use Modelstore object for that purpose.

It means much more coding to have the same result.





{

"order": {

"identity": "70c86603-983b-4bd9-adbc-259436e43cbd",

"version": 1,

"platform": "PowerBuilder",

"mapping-method": 0,

"dataobject": {

"name": "d_order_modify",

"meta-columns": [{

"name": "forderno",

"index": 0,

"datatype": "string",

"nullable": 1

}, {

"name": "fcustno",

"index": 1,

"datatype": "string",

"nullable": 1

}, {

"name": "fstatus",

"index": 2,

"datatype": "string",

"nullable": 1

}, {

"name": "forderdate",

"index": 3,

"datatype": "date",

"nullable": 1

}, {

"name": "ftype",

"index": 4,

"datatype": "string",

"nullable": 1

}, {

"name": "famount",

"index": 5,

"datatype": "decimal",

"nullable": 1

}, {

"name": "fpaid",

"index": 6,

"datatype": "string",

"nullable": 0

}, {

"name": "fdescription",

"index": 7,

"datatype": "string",

"nullable": 1

}

],

"primary-rows": [{

"row-status": 1,

"columns": {

"forderno": ["101008"],

"fcustno": ["1010"],

"fstatus": ["1"],

"forderdate": ["2016-10-17", 1, "2016-08-17 00:00:00"],

"ftype": ["Phone"],

"famount": [72],

"fpaid": ["0"],

"fdescription": [null]

}

}

]

}

},

"orderitems": {

"identity": "70c86603-983b-4bd9-adbc-259436e43cbd",

"version": 1,

"platform": "PowerBuilder",

"mapping-method": 0,

"dataobject": {

"name": "d_orderitem_edit",

"meta-columns": [{

"name": "fcategory",

"index": 0,

"datatype": "string",

"nullable": 1

}, {

"name": "fproname",

"index": 1,

"datatype": "string",

"nullable": 1

}, {

"name": "fdescription",

"index": 2,

"datatype": "string",

"nullable": 1

}, {

"name": "fquantity",

"index": 3,

"datatype": "decimal",

"nullable": 1

}, {

"name": "fsku",

"index": 4,

"datatype": "string",

"nullable": 1

}, {

"name": "funit_price",

"index": 5,

"datatype": "decimal",

"nullable": 1

}, {

"name": "flineid",

"index": 6,

"datatype": "long",

"nullable": 1

}, {

"name": "forderno",

"index": 7,

"datatype": "string",

"nullable": 1

}, {

"name": "famount",

"index": 8,

"datatype": "decimal",

"nullable": 1

}

],

"primary-rows": [{

"row-status": 0,

"columns": {

"fcategory": ["A"],

"fproname": ["Men's T-shirt, Blue"],

"fdescription": ["Men's high quality stretch short sleeve candy-colors T-shirt with round collar, blue"],

"fquantity": [1],

"fsku": ["A00008"],

"funit_price": [12],

"flineid": [5],

"forderno": ["101008"],

"famount": [12]

}

}, {

"row-status": 0,

"columns": {

"fcategory": ["A"],

"fproname": ["Men's T-shirt, Black"],

"fdescription": ["Men's high quality stretch short sleeve candy-colors T-shirt with round collar, black"],

"fquantity": [1],

"fsku": ["A01010"],

"funit_price": [12],

"flineid": [6],

"forderno": ["101008"],

"famount": [12]

}

}, {

"row-status": 0,

"columns": {

"fcategory": ["A"],

"fproname": ["Polo Shirt, White"],

"fdescription": ["Men's top quality short sleeve masculine turn-down collar casual polo shirt, white"],

"fquantity": [2],

"fsku": ["a22222"],

"funit_price": [24],

"flineid": [7],

"forderno": ["101008"],

"famount": [48]

}

}

]

}

}

}

  1. Helpful
  1. Michael Kramer
  2. Wednesday, 27 November 2019 19:45 PM UTC
Sorry, missed that angle. See separate reply.
  1. Helpful
There are no comments made yet.
Michael Kramer Accepted Answer Pending Moderation
  1. Wednesday, 27 November 2019 20:42 PM UTC
  2. SnapObjects
  3. # 2

Let's say your mobile/web app is designed so it matches the resultset of one DataWindow. Let's take the different Insert/Update/Delete actions one-by-one. In real-world same view in the client app may represent data from multiple DataWindows. That just requires more code - but same way of coding and same needs for mapping data between client app's view models and each DataWindow's "data model".

Terminology:

  • ViewModel: The class representing data exchanged with the client app. Very often ViewModel for INSERT/UPDATE/DELETE are different.
  • DataModel: Class representing the rows in the DataStore
  1. INSERT.
    1. Client app delivers a ViewModel object The insert-ViewModel is often a subset of total columns.
    2. Code must map ViewModel object to DataModel object.
      Can be one-line call using AutoMapper or similar mapping tool.
    3. Add DataModel "row" to the DataStore.
    4. Then save changes to database.
  2. DELETE.
    1. Client app delivers a ViewModel holding just the key columns.
    2. For auditing/security maybe some extra data.
    3. Retrieve + Find row in DataStore representing the ViewModel object.
    4. Delete that row.
    5. Then save changes to database.
  3. UPDATE.
    1. Client app again delivers a ViewModel incl. original identity to find the row being edited.
    2. Retrieve + Find the matching row in DataStore.
    3. Map from ViewModel into DataModel representing the matching row
    4. Ensure that DataModel row is updated in the DataStore
    5. Then save changes to database.

So you will need to write more code. But you can still leverage the IDataStore and its capabilities towards the database and ease of  Retrieve/Find/InsertRow/DeleteRow, etc.

Actually I write almost the same amount of code for such "simple", generic scenario as if it had been Entity Framework Dataset<T> instead of IDataStore<T>.

This mapping of data from one object to another thanks to reflection is a strong tool that greatly reduces amount of trivial code and therefore saves tremendous coding/debugging time.

HTH /Michael

Comment
There are no comments made yet.
Ricardo Jasso Accepted Answer Pending Moderation
  1. Wednesday, 27 November 2019 20:47 PM UTC
  2. SnapObjects
  3. # 3

You would need the client to perform the same function that the JSONPackager does in the PowerBuilder application so it can consume the Web API. The client would need to form the JSON data with the structure that the Web API needs, that is, DataWindow insert, update and delete buffers structure. The only practical way I can imagine is to create the client in .NET using the new Appeon .NET namespaces. But for other languages I don't see this feasible.

For what I understand, all this functionality is meant to link DataWindows with Web APIs. Creating Web APIs which could be consumed by other clients in a more generic way would require a different aproach. But the new .NET DataStore could be used as a leverage for internal data access in the Web API.

Regards,

Ricardo

Comment
There are no comments made yet.
Necmettin Urkmez Accepted Answer Pending Moderation
  1. Wednesday, 27 November 2019 20:56 PM UTC
  2. SnapObjects
  3. # 4

Many thanks. Could you provide a small demo project (.NET) for that case? It would be great contribution for knowledge-base of Appeon

Regards

Comment
There are no comments made yet.
francisco Herrera Accepted Answer Pending Moderation
  1. Friday, 29 November 2019 16:44 PM UTC
  2. SnapObjects
  3. # 5

Necmettin Urkmez

Remember you can build assemblies an use them as needed . For example you can create an assembly to communicate with javascript and use it with Angular.  

And as Ricardo said :

"You would need the client to perform the same function that the JSONPackager does in the PowerBuilder application"

Hope this work. 

best regards!

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.