Uniface layers

Author: roger.wallin@abilita.fi (rogerw)

Hi, today it should be almost evident that the Uniface development-product should "encourage" the developer to use a distinct DataAccessLayer (DAL) and BusinessLogicLayer (BL). As you need different kind of UI:s there should be a natural distinct border between the UI and the BL, encouraged by the development tool. DAL: (DataAccessLayer only accessible from BL) DAL.MYTABLE.RETRIEVE(....) DAL.MYTABLE.STORE(...) DAL.MYTABLE2.RETRIEVE(...) DAL.MYTABLE2.STORE(...) BL: (BusinessLayer) BL.MYTABLE.RETRIEVE(...) BL.MYTABLE.STORE(...) BL.MYTABLE.OTHER(...) BL.MYTABLE2.RETRIEVE(...) BL.MYTABLE2.STORE(...) BL.SERVICE1.COMBINEMYTAb1ANDMYTAB2(...) BL.SERVICE2.SOMEBUSINESSLOGIC(...) BL.STOREMYXML(...) BL.BUILDMYXML(...) Uniface UI or Other UI: DeviceResponsive, Desktop, Web, Mobile   You usually publish the DAL, BL and UI in the same place on the same PC or Server. However the distinction between BL and UI should be really clear and distinct. The distinction is clear enough when it also is possible to publish the BL as an open API, eg. as a RestService-API or WebService-API. Do you use Uniface in this way? Should there be more discussions about this and moving towards this kind of developing, encouraged by Uniface? Regards RogerW.

19 Comments

  1. On the principle that Uniface already IS the data access layer, and as such is really quite slow at fetching reasonably large data sets, what kind of behaviour are you separating from the business layer in your (extra?) data access layer? Where do you put the activates for the DL services?  Uniface has built this into the component types/subtypes as the "Entity service" (ESV), but I'll admit I've never understood any explanation of why they are useful enough to put up with them slowing down data access....  Is the referential integrity supposed to go in there, with the business logic in the SSV and then the UI in the FRM/DSP? If so, then implementing the return of the information through three layers to the user interface to inform the user what is wrong adds complexity and difficulty across the board. We normally publish the BL on the server, and the UI on the PC. Except of course that some BL requires interactivity from the UI (when option X is selected only values Y&Q are available for choice....) which does blur the line somewhat.  I think I'd need practical examples of what kind of code lives at which level to discuss this further....  


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  2. Hi Iain, just a short answer/explanation, I'll think about some better answer to the next week. I don't want to specify the DAL and it's interaction with BL. The DAL is just a realization of your Uniface Data-model (table for table), probably as it is realized in Uniface today. Probably you already have a BL, as you publish it on the server. However I  would like Uniface to encourage the BL-programming and thereby making it more easy to switch UI, ie. a BL influencing the whole data-access and programming-logic.  It's also good practice to have a BL and no direct access to DAL, however usually it would just be a redirection of the retrieve to the DAL and if the BL and DAL is published with the client, you don''t even notice it (as today). But again the programmer should in a better way be aware of the distinction between the UI and the BL. It should also be very easy/natural being able to publish the BL as an API accessible by other programming languages or by Uniface UI. It's not good for Uniface (and Uniface programmers) that it's that hard to make Uniface logic accessible to other programming languages and to remote Uniface logic. I claim that today Uniface-development-tool encourages the programmer to put as much as possible in the UI, perhaps because of the retrieve-statement and the way it's working. Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  3. Hi again Iain, Just two questions. Does your BL-server have a connection string to the database?  Does your Client application have a connection string to the database? Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  4. Hi, This is what I need: In the Uniface-Development-Tool a view of your BL, containing chosen "Self contained" services and your Data Models (or a part of those). A button that builds the urr of the BL, wich can be published to your Uniface server. Another button that builds a "Proxy application" (RestAPI and/or Web-ServiceAPI) of your BL and makes it possible to publish it on IIS.   In some way the possibility to change the database connection: $MSS    MSS:myserver:mydb|username|password to $MSS    https://MyWeb/MyUnifaceBL/ After that the retrieve-statement of the client-application would make a call to your RestAPI or Web-ServiceAPI.   Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  5. rogerw said Hi again Iain, Just two questions. Does your BL-server have a connection string to the database?  Does your Client application have a connection string to the database? Regards RogerW.  

    Hi, Well, We have clients (PCs) executing uniface.exe with only very limited occasions to query the database directly (all data is fetched via services run on the server). In a large number of cases the asn for the client does not contain a direct link to the database but instead uses urouter to fetch the data even in 'direct' database lookups.  We then have services which do the database work running within userver.exe on the server via urouter.exe, which contain the 'write level' business logic. (i.e. which fields must be filled in, valid values etc.) Some of which is coded, some of which is built into the model in terms of valreps and relational integrity, some of which is stored in the database and evaluated using $expression, allowing flexibility.  Technically, since those services do not actually have the commands within them to update the database, and are (mostly) database independent, we also have a data layer which is the native interaction between uniface and whatever database we are running on.  I can see why one would and should try to separate UI and BL (for client independence, web, CS, 3GL) and I find that simply exposing my current BL layer as web-services has been relatively easy where necessary.  What I don't see is where the gain is in adding another layer of code which requires maintenance between the BL and the database itself. Both the uniface data access code (inherent) and the relational database code itself seem to me to fulfil the requirements of an encapsulated data layer without coding anything extra on top.  Iain


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  6. Hi Iain, perhaps Uniface urouter is doing what I want, but isn't it complicated. Do you have Uniface urouter on the same server as Uniface server? Have you accessed your userver from outside your internal net? What do you mean by "...., we also have a data layer which is the native interaction between uniface and whatever database we are running on."? Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  7. Well, when we are calling web-services they are routed via the urouter. So yes, we've accessed the urouter from outside the local net.  Uniface client to urouter calls as a standard, no we haven't done that, but there's only one or two ports to re-direct (13000/13001 and the license port) so we could. I think it would be slow to do this however, as the client/server data transfer is both large and frequent.  The three classic layers of object oriented programming are :- UI - The interface between the user and the business logic. In this case, uniface.exe running uniface forms.  BL - The business logic. userver.exe running uniface services DL - Data layer, the interface between the BL and the data stored. - This is the uniface code which uses the model to enforce relational integrity (cascading/restricted deletes etc) and data validation (valreps). Also, if you have migrated it there from the model, this function CAN be implemented in the database itself.  What I was trying to work out, was what functions you felt should 'live' in the data layer, which weren't covered by the relational integrity aspects of either the native uniface behaviour, or the R/I in the database itself.    Practically, however, there is always bleed between these layers. Some business logic must be presented at UI level (changing the selectable values for a field based on other data etc) or we are back to the 'bad' old days of filling in web-forms and being presented with 20 errors for missing/mismatched data on submitting the form. JSON and AJAX have added the blurring of the layres back into web 2.0, and everyone is happier for it.... 


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  8. Also, what is a uniface server where there isn't a urouter? Urouter causes userver.exe to execute uniface code, I don't think you can make it execute userver.exe on a remote machine.  Amything where uniface.exe is executing the code is a client rather than a server surely.... 


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  9. Iain Sharp said Also, what is a uniface server where there isn't a urouter? Urouter causes userver.exe to execute uniface code, I don't think you can make it execute userver.exe on a remote machine.  ...

    Hi Rogerw & Iain, I am following this discussion with a lot of interest...I would like to start contributing giving an answer to Iain: yes, urouter can potentially start a userver on a remote machine; defining an UST on a linux box it could be possible to rsh something but I've never tried to do it...what I've already implemented once (but not in a production env, only to demo!) is urouter chaining: PC client open a connection to urouter which open a connection to another urouter which starts an userver to answer to client calls. Hope it helps... Gianni


    Author: gianni (gianni.sandigliano@unifacesolutions.com)
  10. Hi,

    On the principle that Uniface already IS the data access layer, and as such is really quite slow at fetching reasonably large data sets, what kind of behaviour are you separating from the business layer in your (extra?) data access layer? Where do you put the activates for the DL services? 

    To ignore the extra DAL, I now talk about the CRUD DAL-services as a part of the BL. However I still think there is a CRUD DAL available, represented by the Uniface Data-Model. The activates of  the DL-services are in the user-client, ie. todays retrieve should make a call to the Web RestApi, if defined on such a data-path.  The RestAPI- or WebService-Api that is a proxy of your BDL-services, should redirect to your BDL (BusinessAndDataLayer) on the Uniface-server. This RestAPI- or WebService-Api should preferably only be used for client forms with user interaction.  Talking about "large data sets", you will probably define it as a report. A report should,  at the most, be started via the API and perhaps get some kind of result-log from the API. Otherwise the report should run on the Uniface-server, with a quick connection to the database. Gianni; yes I also think that an urouter can start another urouter, I think I have seen some discussion about it before. However I would really like the idea of an outermost RestApi or WebServiceApi representing your BDAL. Compare this to eg. the ODATA standard. Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  11. gianni said
    Iain Sharp said Also, what is a uniface server where there isn't a urouter? Urouter causes userver.exe to execute uniface code, I don't think you can make it execute userver.exe on a remote machine.  ...
    Hi Rogerw & Iain, I am following this discussion with a lot of interest...I would like to start contributing giving an answer to Iain: yes, urouter can potentially start a userver on a remote machine; defining an UST on a linux box it could be possible to rsh something but I've never tried to do it...what I've already implemented once (but not in a production env, only to demo!) is urouter chaining: PC client open a connection to urouter which open a connection to another urouter which starts an userver to answer to client calls. Hope it helps... Gianni  

    Hi Gianni,  I appreciate that most of this is semantics, and I have indeed chained paths (although in my case client to urouter to userver, back to the same urouter back to another asn for another database.  Regards,  Iain


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  12. Hi, I would be very interested in how you can remote the dataaccess to the Uniface server, ie. handling a normal retrieve in the client without having a database-connection on the client. Can Uniface do this automatically by the urouter and retrieve statement? Can I generate  "3-tier" services for the Uniface server or do I have to do my own service programming? Regards RogerW. PS. Perhaps this is already dummy questions for those having used these techniques.Embarassed


    Author: rogerw (roger.wallin@abilita.fi)
  13. With urouter in place and a 'server' asn file which points at the database you can set up a path in the 'client' asn file as follows.  Replace  $OD1 OD1:odbc.dsn:|| with  $OD1 TCP:server|userver|password|data (Possibly with an /ex sign on the end) We use this extensively to connect to sage accounts from our application, because then the ODBC data source only needs to exist on the server.  The server asn file then has the $OD1 OD1:odbc.dsn:|| stuff (but you NEED to have the password built in (I think).) Since the password cannot be fed in manually, any database level tracking you have of who did the changes is lost....  Also, we have certain times when the urouter monitor shows the UST as "Idle has context" and we have no idea who or what has the context. 


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  14. Thanks Iain, and then you just code a normal retrieve or store on the client, no extra services on the Uniface server? Have you noticed something going strange compared to having a direct connection to the database, transaction problems etc? Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  15. Yes, you can just use it as a database transaction. We mostly use it for reading not updating, all our CRUD for our 'standard' data tables runs via services anyway, so it's not so necessary, but we HAVE updated using it, and didn't see any significant transaction issues. It's all handled by uniface. (Which is what I meant by Uniface being the DL, you can redirect data paths to one or more databases 'invisibly' to all uniface processes.  All of this is made a little more troublesome for us because we use crystal reports for printer/dashboard details, and that obviously can't access the urouter. But for 'pure' uniface transactions it's not a problem.  I would like some form of ODBC driver which sat on top of urouter (so we COULD point crystal at an ODBC DSN which then used uniface to decide where the data resided and passed the SQL to that database.) that way we could do without 'direct' data access from the client at all and wouldn't need to install any other ODBC drivers at client level. But I appreciate that would be either limiting (no redirection of data paths for individual entities) or practically impossible, because uniface would have to disassemble the sql script and re-path each table.... 


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  16. Ok, then it's time to do a summary. Actually I started this topic to have as support for a decision about using Uniface web-programming or not. It somehow turned to some problems I have had with Uniface desktop programming, but here the conclusions. Feel free to continue the topic. 1. There is no need for an WebRest- or WebService-API for the CRUD operations. At least we, don't have the need for this kind of communication and it will probably not fit into the Uniface product. A big problem is the transaction handling. If you use other programming languages than Uniface, they usually have their own effective way of handling CRUD operations. 2. Other kind of communication between applications and especially applications built with other languages than Uniface, can be handled by WebServices and/or RestServices, and in a pure Uniface environment by Uniface services in common UARs or published on the Uniface Server.  3. Uniface handling of web-services, both call-in and call-out, should still be improved. Uniface has problems with complex types, etc. 4. At least we, need more support for using IIS as web-server, both regarding web-services and other Uniface web-programming. If I remember right some Uniface-consult recently said that Uniface only supports Apache. Is that true or is it just a matter of correct installation and settings? Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  17. The uniface stuff is run by Tomcat, but you can integrate the tomcat and IIS settings on the same machine so the overall web page can be served by IIS but redirected to tomcat for one or more virtual folders. 


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  18. rogerw said ... 1. There is no need for an WebRest- or WebService-API for the CRUD operations. At least we, don't have the need for this kind of communication and it will probably not fit into the Uniface product. A big problem is the transaction handling. If you use other programming languages than Uniface, they usually have their own effective way of handling CRUD operations. 2. Other kind of communication between applications and especially applications built with other languages than Uniface, can be handled by WebServices and/or RestServices, and in a pure Uniface environment by Uniface services in common UARs or published on the Uniface Server.  3. Uniface handling of web-services, both call-in and call-out, should still be improved. Uniface has problems with complex types, etc. ...

    Hi Roger, IMHO there should be always be a reasonable balance between a live set of internal calls to implement CRUD support at document level with base programming language (maybe/probably Uniface in our cases) and a real API to be available to all kind of external programming languages to access same data. Main programming language should be considered the "master" of application data; other programming languages are simply "slaves". (Sorry for this wording!) Stability over periods is the key differentiator: internal calls are often adapted in each change management loop/project while API should maintain a major stability considering the inducted overhead to other companies/organizations. Only from time to time API includes latest production changes implemented / tested / delivered. In my consultancy role I've often proposed to have the API incapsulating internal calls; in this way the intermediate code could be used to maintain higher stability to Web/Rest Services API. Hope it helps... I would like to ask you an example about your sentence: "A big problem is the transaction handling. If you use other programming languages than Uniface, they usually have their own effective way of handling CRUD operations.". IMHO transaction handling at document level is almost indipendent from the programming language you use. Feel free to answer privately if you prefer... Thanks you both for this nice discussion! :-) Regards, Gianni


    Author: gianni (gianni.sandigliano@unifacesolutions.com)
  19. Hi Gianni, I'm not sure that I understand what you want me to answer on. However, what I meant is that  it's perhaps after all a bit overkill to include the CRUD operations in a WebApi. Having thought about it, I don't see the immediate benefit of it. Other programming-languages won't use it. Using Uniface you will have access and is able to use the Uniface internal ways of accessing the database, and you have the possibility to remote the data-access in different ways. Considering web-programming you are partly already inside the internal net and so the CRUD operations are usually not a problem. A CRUD webApi would perhaps be of interest thinking about a mobile application processing on the phone. Transactions and CRUD WebApi. It's not that clear how to initiate a transaction in a stateless CRUD WebApi and let the transaction live longer than one call. Think about two store-operations and you want to rollback both. Hope this somehow clarify my thoughts. Regards RogerW. 


    Author: rogerw (roger.wallin@abilita.fi)