OE 11.5.1 Business Entity - datasource with additional param

Posted by bingo on 10-Aug-2015 01:41

Hello,

I have a question concerning OE Rest 11.5.1 Business Entity with Kendo Datasource.

Is it possible to send addition field/value pair within the filter json parameter to the Rest Service.

If not, is it possible to assign to another input parameter e.g.

METHOD PUBLIC VOID ReadTable(input filter as character, INPUT q as character, output dataset dsskumastr):

An example within the input filter parameter:

@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="true").

@progress.service.resourceMapping(type="REST", operation="read", URI="?filter=~{filter~}", alias="", mediaType="application/json").
@openapi.openedge.method.property (name="mappingType", value="JFP").
@openapi.openedge.method.property (name="capabilities", value="ablFilter,top,skip,id,orderBy").
METHOD PUBLIC VOID ReadTable(INPUT filter AS CHARACTER, OUTPUT DATASET dsDataset):

only see - filter: {"skip":0,"top":10}

...

define variable q as character no-undo.

jsonParser = NEW ObjectModelParser().
jsonObject = CAST(jsonParser:Parse(filter), jsonObject).

q = jsonObject:GetCharacter("q") NO-ERROR.

...

The Kendo Datasource enables additional parameters using the tag below.  However I'm unable to find any parameters mapped on the server end.  

I was able to map additional parameters when using json datatype but the OE service was not using Business Entities, but rather the standard OE Rest Service.

dataSource: {

   type: "jsdo",
   serverPaging: true,
   serverSorting: true,
   serverFiltering: true,

   data:{ q:"xxxxx"},

   transport: {
      jsdo: "dsDataset",
      tableRef: "ttname",
      countFnName: "count",
   },
},

 

I'd read you can use the datasource filter tag but the variable I'm using is not for use in the where clause.

Any suggestion is appreciated.

Posted by egarcia on 10-Aug-2015 07:08

Hello,

The JSDO and the Business Entities use a prescriptive approach which works with a specific signature.

(We may add support for additional/custom signatures in the future.)

The Kendo UI DataSource type: "jsdo" uses the JSDO internally, which then uses the information on the JSDO catalog to determine the URLs to call for the CRUD operations.

The transport.read.data option in the Kendo UI DataSource is no current used.

(In your example, the data property seems to be at the DataSource level, I would expect to see it at the transport level.)

Depending on your goal, there are some few ways to work around this model.

Do you need this parameter to be send only for READ or for all the CRUD operations?

Do you handle reads programmatically or is it being done by the UI component?

Does the parameter change from one operation to the next one?

Here are some few options:

- Use the jsdo.fill() method to read the data into the JSDO memory. You can use the string parameter to pass a string with the format that you need to the server.

- Use an invoke operation to read the data from the server and use addRecords() to add the records into the JSDO memory.

- In a future version, we could add support for using the data property in the transport and pass it to the server as a "capability", either using mappingType=JFP or a custom plugin.

- In a future version, use the context APIs to pass context to the server.

Please let me know if you are interested on using any of these approaches and I can provide details on using them.

Thank you and regards.

All Replies

Posted by Mike Fechner on 10-Aug-2015 01:58

Hi Bingo, not answering your question ... but if you care about Business Entities in general, this might be interesting for you:

community.progress.com/.../19448.aspx

Posted by egarcia on 10-Aug-2015 07:08

Hello,

The JSDO and the Business Entities use a prescriptive approach which works with a specific signature.

(We may add support for additional/custom signatures in the future.)

The Kendo UI DataSource type: "jsdo" uses the JSDO internally, which then uses the information on the JSDO catalog to determine the URLs to call for the CRUD operations.

The transport.read.data option in the Kendo UI DataSource is no current used.

(In your example, the data property seems to be at the DataSource level, I would expect to see it at the transport level.)

Depending on your goal, there are some few ways to work around this model.

Do you need this parameter to be send only for READ or for all the CRUD operations?

Do you handle reads programmatically or is it being done by the UI component?

Does the parameter change from one operation to the next one?

Here are some few options:

- Use the jsdo.fill() method to read the data into the JSDO memory. You can use the string parameter to pass a string with the format that you need to the server.

- Use an invoke operation to read the data from the server and use addRecords() to add the records into the JSDO memory.

- In a future version, we could add support for using the data property in the transport and pass it to the server as a "capability", either using mappingType=JFP or a custom plugin.

- In a future version, use the context APIs to pass context to the server.

Please let me know if you are interested on using any of these approaches and I can provide details on using them.

Thank you and regards.

Posted by bingo on 10-Aug-2015 19:41

Hello Egarcia,

Thanks for your reply.  Currently, I'm only working with the read operation and through the Kendo UI components.

The parameter/s I require to be passed across to the back end will do a few database queries to construct a specific filter before the fill operation and will include abstract data mapping across multiple tables.  

I probably can work around this with the Add/Update by assigning parameters to the dataset temp-table fields then accessing them on the back end.  However with the read, there is no option for that.

The options you suggest appear to be done programmatically so I'm not sure how it would be possible to still pass across the back end and hook to a UI component.

Any thoughts?

Thanks

Posted by egarcia on 11-Aug-2015 15:15

Hello,

Thank you for the additional information.

As mentioned earlier, the JSDO does not currently use the transport.data property of the Kendo UI DataSource.

I have entered a report to consider this as a future enhancement.

Please contact Product Management to specify a priority.

Following are some few suggestions that you can do today if you need a workaround.

1) Use the filter property in the Kendo UI DataSource:

> I'd read you can use the datasource filter tag but the variable I'm using is not for use in the where clause.

You could pass the parameters using the filter property and process the filter (ablFilter) received on the server to read the parameter and obtain the actual filter for the where clause.

2) Specify your own mappingType in your Business Entity and define a plugin on the client side to pass the parameters.

This approach uses functionality that is used internally to support the JFP (JSON Filter Pattern) mappingType.

Please notice that this suggestion is using a feature that has not been documented and it is not officially supported.

Also, please consider that the feature could change in a future release and you may need to update your code.

Here is how you could do it.

You can specify your own mappingType in your Business Entity using the method.property annotation for the READ method:

@openapi.openedge.method.property (name="mappingType", value="MYJFP").

You can define a plugin to process the parameters for the READ operation using:

   progress.data.PluginManager.addPlugin("MYJFP", <function> );

You can look at the the code for progress.all.js to see how the JFP plugin is registered and has the base code for the JFP plugin. Alternatively, you can look at the myjfp.js file in following example:

   oemobiledemo.progress.com/.../example025.html

Notice the assignment to jsdo.mydata in example025.html and its usage in the plugin code in myjfp.js.

You can change the JFP code in your Business Entity to access the the new properties.

I hope this helps.

Posted by bingo on 12-Aug-2015 02:04

Thanks,

I'll have a look at option 2 and see how it goes.  However as you mentioned, this is not officially supported and might cause issues with a newer release of the Business Entity.

I did try option 1 but it becomes really messy trying to separate required clauses and data mapped field.  In this case you have to reconstruct a new where cause rather than setting the value.

Posted by Marian Edu on 03-Dec-2015 01:50

Hi Edsel,

the CCS still requires NDA for the moment but wanted to say something about the JSDO Kendo data source for some time so there it goes :)

- I know it was probably fun to build the where clause in JS on the client side but you should rather stop that and implement the parse logic in BE base class, this just opens the door wide open for 'sql injection' attacks and many are don't even aware of the fact.

- count property, would be maybe better to simply get the count on the same request a data batch is returned. Kendo does support this and we use it with strongloop data source to not only avoid making two calls instead of one for each data page requested but mind you this also means the filters are parsed twice, same for the query open so it's not really something to be neglected.

I won't start any rants about dataset usage there nor the before-image importance since those seems to be a given for OERA BE's :)

Cheers,

Marian

Posted by Ruben Dröge on 03-Dec-2015 02:55

I agree with you Marian. Parameters should be sent to the back-end instead of a 'finalized filter'. Parameters can then be used in the back-end to setup the filter mechanism.

Posted by egarcia on 03-Dec-2015 04:36

Hello Marian,

Thank you for your feedback.

Yes, you should be able to validate the input passed to the server.

A filter should not be accepted without validation whether it is in a final form or not (if the filter is not in a final form, it just depends on what the parser does and it could also be tricked).

Passing only the parameters to the server makes it easier to validate them. (Parameterized queries would also help.)

You should be able to use the approach mentioned above where you define your own plugin to pass parameters to the server. (I entered a report to consider this as a future enhancement so that it is supported and documented.)

Regarding the count function. The reason why a separate request is done to the server is because we did not want to change the signature of the READ method at the time and the JSON representation for the DataSet does not provide a way to include additional properties. Also, using an HTTP header to return the count is not possible with a Data Object service.

(The filter is only processed once since it uses the result from the READ request.)

We have added a context feature that would allow you to pass data to the server and from the server to the client via HTTP headers (you can use it with a REST or a WebSpeed based service). If you are interested, you could use this feature to return the count on the READ request.

Thanks again for your feedback.

Edsel

This thread is closed