Architecture Study
Architecture Study
Beneficios:
● Promotes abstraction of reusable services
● Optimizes lifecycle independence
● Minimizes impact of change
Disclose Assemble
Why Architect is important?
- User Stories, Personas and Roles - Isolate reusable logic from
Drives Consensus | Manages Complexity | Reduce Risk | Supports Planning |
- Information Architecture integration logic
Facilitates Change | Reduce Cost
- Integration Technology - Apply known design patterns
- User Experience Expectations - Do not join concepts with different
ISO/IEC 9126:1991:
Organize lifecycles
Usability | Functionality | Efficiency | Maintainability | Portability | Reliability |
- Meter nas layers do canvas - Join conceptually-related concepts
Security Compatibility
Why Should we Adopt a Naming Convention?
Impacts of Lack of Architectural Concerns ● Reveal the nature of each module
Poor service abstraction ● Enforce the reference architecture
● Business concepts not correctly isolated and abstracted. ● Normalize known patterns
● Business rules spread over different systems, and little to no code reuse
Unmanageable dependencies
● Systems not isolated from each other.
● Updating or replacing a system has a cascade effect on other systems.
Inflexible and slow-moving legacy systems
● Adapting legacy systems to business changes may be difficult.
● Changes in complex and inflexible systems can take a long time.
When fetching data from an external system of records we can classify two types of However, this pattern has several limitations:
fields, according to the nature of data to understand your integration needs: - Extra load on the ERP each time data is retrieved.
- More perceived latency caused by extra online communication
- Summary fields: Used for listing or searching entries. Typically these fields don’t with the ERP.
change over time, like a Customer name or change very rarely like the Customer - Impossibility to maximize the power of OutSystems Aggregates
city. and Advanced Queries to retrieve Customer data or to combine
- Detail fields: Only required to display details for a single entry. These fields are it with other information.
more subject to frequent changes and to be considered sensitive to be replicated, - A constant need to extend Customer_IS and a strong
dependency on the ERP team to provide new APIs each time a
different data retrieval is required (e.g.: to filter with some criteria or to include must be careful to make sure that the update is successful and synchronously
more or less detail). Typically, to avoid this dependency, developers tend to committed in the ERP first (a write-through policy).
inappropriately reuse the available API, for instance, by using a method that
returns 50 fields, when only 4 are required.
Benefits: Challenges:
Benefits: ● Data is always up to date ● More hits on external system
-Data is always up to date ● More latency
Challenges: ● More APIs - one per retrieval use case
- More hits on external system
- More latency Isolate synchronization logic (Batch Sync)
- More APIs - one per retrieval use case When the synchronization process is too
complex and constantly tuned, it is
Cold Cache Summary Data (Local Replica) recommended to extract it from the
When you feel the need to improve the performance of your Core Service, further isolating
integrations with external systems, a good starting point is
Customer_CS from the external system.
to cache data that doesn’t change frequently. This data is
called “cold data”, that gives the name to this caching
pattern, Cold Cache. Another reason to do it is when the
synchronization requires to orchestrate
Cold Cache is used when it is too costly to synchronize the several integrations - for e.g., If
entire database, and detail is only required for single entries Customers are stored in one system and
(not lists). While summary data must be present to search for any entry, Customer Contracts in another, then the
synchronizing the entire entry is unnecessary when only 10% of them will be actually
synchronization needs to make sure that
visited in detail.
customers are synced before contracts since contracts refer to customers.
When this pattern is implemented: Consumers of Customer_CS don’t need to be impacted by the synchronization
- Only summary data that it’s frequently listed, joined or searched is cached (full code. Additionally, if in the future the ERP is deprecated and replaced by
detail for a single entry can be fetched directly on the external system); functionality built in OutSystems, stripping out the synchronization code has no
- Full and frequent synchronization is avoided (summary information doesn’t impact.
change often) In this example, Customer_Sync is the one regularly fetching updated information
through the Integration Service, to sync into Customer_CS. Customer_CS still
Cold Cache with Batch Sync (Local Replica)
When implementing a Cold Cache, the simplest design approach is to create the consumes Customer_IS to perform online transactions.
caching data model and set up a batch synchronization process to manage the
cached data.
Pros Cons
Adding local entities to Customer_CS will overcome the limitations of the Direct ● Simpler Integration API ● Data may be outdated
Integration pattern and actually create a full-blown Core Service. ● Enable data mashup in OutSystems
● Less impact on external system
● CS consumers not affected by sync
The Integration Service becomes simple and stable. Instead of providing a myriad
of actions for different data retrieval needs, it only has to supply a method to fetch
all customer relevant data, updated since the last sync.
Transparency Service
When there are multiple sources for the same type of information, usually with
different formats and APIs,
the synchronization process
becomes more complex.
Customer_Sync orchestrates
the synchronization with all
Systems of records, updating a
single Customer data replica in
Customer_CS. This creates a
transparency service.
Ordered real-time sync In this example, Customer_CS is not able to update Customers. This pattern is the
If the external system is prepared to fire multiple update requests concurrently most common transparency service, where information comes from different
sources but does not flow in the opposite way. Examples are electricity or toll
readings coming from different sources/formats. They can be corrected or fixed
locally, but never sent back to the source.
Authentication
1. Lack of session redirects to login flow 1. Lack of session redirects to login flow
Foundation Services 2. Login Form 2. Login Form
3. Login with standard system actions 3. Authenticate
and proceed to the original URL 4. Proceed to the original URL
Core Patterns
How to implement?
- Expose entities as read-only
- Create public CRUD operations to centralize business logic needed to change
Entity data
- Entity data can be read using queries or the Get Entity Action
- No circular references between CS modules -> create a BL to deal and support the ○ Large footprints
composite process. ○ Slow deployments
○ Concurrent lifecycles
Extract a Core
—-----------------------------------------------------------------------------------------------------
Validation Rules for Applications
1. Layer Your Modules Correctly - Respeitar as regras de validação de modulus
2. Layer Applications Correctly - As mesmas regras dos módulos aplicam-se às
apps. End-user applications should not provide services to other applications
3. Don’t Mix Owners
4. Don’t Mix Sponsors
1. Identify consumed elements
—-----------------------------------------------------------------------------------------------------
2. Clone the module
Refactoring
3. Rename the original module to (Name)_CS and the clone to have the same name
How Should We Start?
as the original module
1. Modules can have many issues to be fixed
4. Keep consumed elements and their dependencies in the new Core module
2. Performing large scale refactor is often not compatible with development of new
5. Remove elements kept in the Core from the cloned module
features -> Freeze developments during a large period of time
6. Reference the elements in the new Core module
3. We should follow the prioritization criteria
Moving Elements Between Modules
Prioritization Criteria
Elements Without Data Persistency: Actions | Structures | Blocks | Screens |
1. Upper and side references to End-user modules
Elements can be safely moved to other modules | Be careful with consumers!
2. Direct cycles between Core modules
Configurable Elements: Timers (Schedule properties) | Site Properties (Effective
3. Upper references to Core modules
value) | Web Services and References (Different endpoint if target module has (or
4. Direct cycles between Foundation modules
gets) different name & Effective URL | Roles (Relation between Roles and Users)
- In each criterion, always select the module with more consumers first. It will
Moving Processes: New process instances will run in the target module
solve more findings
1. Copy process (old process instances continue to run)
- Do not follow the prioritization criteria blindly. Consider the impact of each
2. Untrigger (desativa o trigger dos antigos processos)
individual refactor and Plan to minimize risk
3. Deploy in all environments
- Development of new features on refactored modules must be frozen. Also
4. Delete old process (depois de todos os timers já estiverem a correr)
applicable for maintenance
Moving Entities Between Modules: Only movies the Entity’s logical definition.
Most Common Use Case
Physically, it is another database table (os dados ficam na tabela original)
● End-user modules providing services
1. Copy Entity to the target module.
○ Denormalize to promote parallel data
2. Run Refactor component to populate the Entity in the target module.
fetching
3. Full compilation with a solution with all target modules, without changes in the
● Leads to:
references.
○ Harder maintainability
4. Update the reference.
○ Slower evolution of the apps
5. Publish changes. Lightweight Local Storage
—---------------------------------------------------------------------------------------------------
- Do not copy the server data model - Do not store too much date
Mobile Architecture Top Principles
○ Define only used attributes ○ Keep only the relevant records
- Think Lazy Load: Event driven development and parallel data fetching
○ Group relevant information
- Use Local Storage: Think use case and optimize content
○ Denormalize local storage
- Avoid Server Calls: Expensive and leads to a bad User Experience
Local Storage Access
Mobile Events
● Avoid table dependency ● Leverage the asynchronous
On Initialize: Occurs before navigating to the Screen and fetching data ○ Denormalize to promote parallel data parallel data fetching
On Ready: Occurs after the DOM is ready, before the transition starts fetching ○ Avoid cascading Aggregates
On Render: Occurs right after the OnReady Event Handler and every time the data ● Avoid generic tables in Events
changes ○ Keep only the relevant records
On After Fetch: Occurs after data is fetched and before data is rendered Server Calls
On Parameters Changed: Occurs in a Block whenever the parent input parameters
change ● Limit server calls as much as ● Use server calls for:
possible ○ Online transactions
On Destroy: Occurs before destroying a Screen/Block and removing it from the
○ Denormalize to promote ○ Synchronization process
DOM parallel data fetching ○ Accessing (and storing) sensitive information
Think Lazy Loading (Revisited)
X Avoid using Event Handlers to fetch data Calls to Backend Systems
Fetching Data on Demand ● Avoid direct calls to ● Doing it raises problems with:
- Data can also be fetched only on demand. Aggregate or Data Action is only backend systems ○ Security - Exposes internal services
triggered explicitly and Still runs asynchronously ○ Performance - Cannot cache / optimize information
- Aggregates can depend on the output of other Aggregates / Data Actions server-side
○ Maintainability - Code is harder to maintain
Empty State Sync Best Practices
- Design and display an empty state image. While the dynamic content is being
● Use Entity bulk operations ● Only synchronize relevant data
fetched ● Only synchronize differences in data ○ Per business case
- Choose images that assure a smooth transition. Blurred gray line or spinners ○ Use timestamps to control ○ Which records do we need?
○ Which attributes do we need?
Prioritize Content Rendering
Synchronization Tips
1. Display relevant content first
2. Delay rendering the secondary content X Do not sync on every Screen or online ✅Sync only when required
- Secondary content in a Block inside an If’s True branch event ✅Sync only what is strictly required
X Avoid long syncs in a single ✅Ensure sync granularity
- Empty state on the False branch
transaction
- The variable influencing the If Condition is set to False by default
- OnRender Event sets the variable to True
Optimize List Loading
- Fetch data on demand, not all at once. OnScrollEnding event to fetch the next set Avoid Monolithic UI Modules
of records
- Avoid expanding content in the list items. Leverage UI patterns
Use Local Storage
- Optimize local storage per mobile app
- Cache data in Local Storage. Benefits: Less server calls | Best performance | Ready
for offline scenarios
● SSL Pinning avoids man-in-the-middle attacks
● It works client-side and adds a verification of the server certificate
—-----------------------------------------------------------------------------------------------
Base Style Guide Architecture: A document that establishes a clear, consistent and
unique visual form of communicating a brand. Live documentation with brand
theme, colors and patterns.
● Custom Theme
references a Base Theme
● Custom Template is
cloned from a Base
Template
● Base Theme and Base
Template can be from
OutSystems UI or other
Theme
—----------------------------------------------------------------------------------------------------
Pro: Keep inheriting new
Questions:
changes and benefits introduced in the Base Theme
1. Why is it important to have a good architecture design?
Con: Lower performance (extra imports of CSS and other resources)
2. Uma imagem do discovery, de uma aplicação a ser consumida por 6 aplicaçoes.
Clone a Built-in Style Guide: Use when introducing extensive changes to the theme Qual a melhor maneira de melhorar o lifecycle da aplicação. As 6 aplicações eram:
- 4 de end-user
● Custom Theme clones a - 2 de core.
Base Theme Os módulos a serem consumidos eram: 2 CS e 4 Foundation.
● Custom Template is R: Separar todos os módulos consumidos para uma aplicação de core.
cloned from a Base
Template 3. Uma imagem de duas aplicações a consumirem o mesmo style-guide. Tinham o
● Base Theme and Base mesmo look and feel mas tinham autenticação separada. Perguntava qual das
Template can be from opções melhor descreve a situação.
OutSystems UI or other R: Usar o built in theme da OS e ter o login no template
Theme
4. OutSystems enforce the naming convention ?
Pro: Best performance by R: No but it recommends
avoiding extra indirection
5. Why create a BL module?
Con: Does not benefit from new versions of the Base Theme
R: Isolated business logic (actions) or Core widgets (Blocks)
Build Your Own Custom Style 6. Image of Connector Pattern. A diferença entre um connector pattern e um
Guide: Use when the custom Style extension pattern
Guide cannot benefit from any R: Um connector pattern tem dois módulos, um que vai buscar o serviço
existing Theme externo e outro que se liga a este pra abstrair da lógica da integração.
● Custom Template is cloned from O extensio pattern é diretamente ligado à extensão ou serviço externo
the Base Template
● Start with the OutSystems UI 7. Em qual caso se deve usar um modulo Drv
Base Theme, since it contains the R: Integration with different systems that perform the same type of
minimum required structure operation
8. Freeze a feature before refactoring: why?
R: Performing large scale refactor is often not compatible with
development of new features -> Freeze developments during a large period of time
9. Diz que resolveste uma circle reference em módulos Core, e a pergunta é qual o 21. Which of the following options describes a valid reason to create a
próximo passo na priorização. Calculation Engine (_Eng) module?
R: Upper references to Core modules R: To support complex calculations (e.g. an insurance simulator).
10. Scenario with upper violation and how to fix it 22. Why is it so important to adopt a naming convention in our applications?
R: To reveal the nature of each module. To enforce the reference
11. A imagem do refactoring de um módulo de end-user com entidades. Porque é architecture. To normalize patterns.
que é importante manter o nome original do módulo no módulo clonado.
R: Por causa do URL das páginas 23. When moving elements between modules in OutSystems, to which elements
should we pay extra attention to and act more carefully?
12. Issues caused by cyclic references R: The elements with data persistency, like Entities. When moving an Entity,
R: only its logical definition is moved. Physically, it is another database table.
13. Problemas causados por upwards references 24. What is the major evidence of bad architecture we can find in this application
R: canvas?
18. In OutSystems, is it recommended to join unrelated concepts in the same 26. In which of the following scenarios should a custom Style Guide be
Module? Implemented?
R: No, because it prevents the lifecycle independence of concepts and adds R: Whenever applications cannot benefit from any existing theme. The
unnecessary impacts to consumers. Style Guide should be implemented by starting from the most basic template
possible, since it only contains the minimum required structure to start.
19. Consider the following statement: “In OutSystems 11, it is recommended to use
business-related Screens in Foundation layer modules, since it does not break any
Architecture validation rule.” Which of the following options is correct ?
R: The sentence is false. Although all references to Screens are weak, only
non-business related Screens should be used in Foundation layer modules.
20. Consider that we have a weak side reference between End-user modules. What
is the best way to remove that reference to avoid an architecture violation?
R: Weak side references between End-user modules are allowed, so we do
not need to remove that reference.