Data Layer Best Practices

Data Layer Best Practices

Hello All,

I'm trying to isolate all my data requests onto a separate module, when dealing with inserts and updates I dont seem to have a problem.  

However when I try to isolate my data within a Preparation Action my solution seems awkward. 

I'm able to create necessary logic to retrieve a list of Instructors using Aggregate, but in order to replicate the functionality inside Preparation I must assign the Aggregate output to the output parameters List and Count

For fetching the first time this seems to work as all screen mapping work fine 

My problem occurs with the Refresh Data Inside RefreashInstructorTable, Refresh Data component cannot be used as there is no data source to map to, so I replaced it with a call to my referenced action GetInstructions which is automatically renamed GetInstructions2, and since this call is different and not mapped to my TableRecords widget I must map it's call to the first  GetInstructions values 

Now for my question:
  1. Do architects resign themselves to not using a data layer when it comes to the Preparation Action or
  2. There's a clever solution out there that I am missing.


Jean Mercier
Hi Jean,

This is a common misconception about how to architect applications in OutSystems Platform. I totally relate to creating an API to access the data for reading or for writing this is how I used to look at it. However OutSystems Platform introduces a different way of thinking this thru. Let me give you an example. This same action that you have here is actually not such a good idea. OutSystems Platform can determine the best optimization for the aggregate based on the number of records it needs to use and the actual attributes it will use on the screen. This means that without the developer having to worry about it the columns and the rows fetched from the database are optimized for the implementation. And this changes automatically as you change the implementation so if you have to use one more attribute, just use it. Encapsulating this logic in an action results in either loosing all these optimizations - every column and every row fetched from the database - or having a lot of inputs and much more complex logic inside the action to deal with all these cases. This is just the tip of an iceberg. I do believe that when it comes to OutSystems Platform creating modules based on 3-tier architecture (data, logic, ui) is really a bad idea. Our approach for create a modular architecture is much functional and business centric than tier-centric. Usually I use the joke that a module in outsystems is already a 3-tier module because you can work the full stack righ there. Take a look at the videos we have on the online training regarding this topic starting with this one.

I hope this helps.

Thanks for replying and have watched the online seminars on this topic.
Ok I get the optimizational benefits of using an aggregate, and I'm more of a person that prefers to work with a tool than against it.  Let me explain a scenario and maybe you can explain how it would fit in your functional business centric scenario. 
Lets say I have a module I will call Party, a party can be a person or an organization it's highly complex and deals with everything you can think of in creating or updating a person or organization including age (sex or org type) address etc...
Now I'm building a Dance Studio Manager app which has to create classes and these classes have instructors that I need to create and assign to these classes, since these instructors are persons I'd like to use my party module to create them and there is a method to create them and list them.
In this "functional business centric scenario" how do I go about getting the information to list all my instructors from an aggregate within a Preparation Action inside my Dance Studio Manager app, now that the data resides in a different module.
Jean Mercier
Watch the Reuse an Element in Another Module lesson. Architecture wise in the module where you decide to have the Instructor entity I would set this entity as public but read-only (which is the default) and create a public action to control how information is written to this entity. As for the reading once the entity is public you can reference it in other modules and use it in aggregates as you see fit.