I am working on a huge application which would end up having 30+ e-spaces collectively for all layers. Per 4 Layer Canvas Architecture, I know that entities specific to End User layer modules would reside in respective modules and those business entities which are common to more than one end user modules would reside in e-spaces which are at Core layer.

Therefore for entities which are in End User Layer modules I can keep their "Public" property as "No" and "Expose Read Only" as "No". However for entities which are in Core Layer e-spaces, there are two options:

1. If "Expose Read Only" is set to "No" and "Public" set to "Yes", the referencing modules would be able to perform any write operation on those entities, but this would compromise the security of data in those entities as any other application modules on the same server would also be able to reference them and perform write operations. But with this approach, the developers would be able implement their logic in respective End User layer modules to write/update data in core entities and would also be able to debug code easily.

2. If "Expose Read Only" is set to "Yes" and "Public" set to "Yes", the referencing modules would be able to reference Core layer entities but won't be able to perform any write/update operation directly in End User layer modules. To perform write/update generic server actions would have to be developed but it would be very tedious and complicated task keeping in mind the complexity of application. And if there are no generic server actions developers would end up implementing several server actions on Core layer to accomplish their tasks which is not what we want. Also, this would make code debugging a bit difficult for developers as they would have to switch between modules.

I can go with mix of two approaches but there would be very few entities (hardly 4-5%) where I can use the second approach.

Please suggest best design approach in this kind of situation.

Hi Junaid,

The second option is what we always use: have CRUD actions in our Data layer for every read-only Entity (usually a single "EntitySave" that doubles for CreateEntity + CreateAndUpdateEntity). Depending on what kind of data we write, we might put a "combined" save Action in the Core Services layer that saves multiple related Entities at once, or have a Save action in the Core Services (or, depending on the type) Business Logic layer that does some further checking for valid combination of values etc.

Hello Kilian,

Sorry for responding late, but I am still not clear about the purpose of exposing the entities with "Expose Read Only" as "Yes" to other modules. The server actions at core layer too are doing the data modifications and they are public to all other modules, so how is it helping me secure my data? I understand there may be cases for certain entities where a server action can be reused, but this cannot be followed as thumb rule for all entities.

And I think by statement "The second option is what we always use: have CRUD actions in our Data layer for every read-only Entity ", you mean that you follow this for read only entities, but there may still be some entities which you don't keep read only based on business requirement and allow consumer module to use the Outsystems provided entity level Create/Update/Delete methods on them.

Junaid -

That makes sure that no other eSpaces can directly save data to the entity and work around your CRUD actions. The CRUD actions perform your update, create, and remove logic on their own, the consumer eSpaces should NEVER be calling CreateXYZ, CreateOrUpdateXYZ, DeleteXYZ on their own, they should be calling your actions.


Hello Justin,

This is what I am trying to understand, in either case (CRUD actions or entity methods) we are allowing the consumer modules to perform create/update/delete on core entity data. Therefore in terms of data security none is better than the other, are there any other good reasons to choose server actions over entity methods? 

Actually mine is a huge application and before defining any approach for entire application, I am looking for enough reasons to justify it to my team. I hope you guys understand.


Junaid -

What you are REALLY saying is:

"We want to find the equivalent of a 'protected' or 'friend' access instead of 'public'", right?

There is no equivalent, Actions are either "Private" or "Public" to put it in C# or Java terms.


The benefits of creating the server actions:

* You have a single place to perform validation, logging, and so on

* If there is business application logic (like removing child records when you remove a parent, or enforcing a "new record on every create, deactivate the previous record" pattern) you can do that in one place instead of HOPING that consumer developers remember to code that logic.

* It is very easy to expose these Actions through a Web service for architecture reasons or for testing purposes (very easy to unit test with Postman or SoapUI or whatever)

* There is a single place to handle error messages and translations