This article aggregates a collection of best practices and conventions that you can apply when developing your OutSystems applications. These are only recommendations and you should adapt them each environment and to each development style.
Naming and coding conventions
- Use English for code and comments.
- Meaningful names (for example, "Customer" instead of "Cstr").
- Use PascalCase.
- Suffix foreign keys with “Id” (for example, "CustomerId").
- Include the Entity's Name in the Record's name (for example, "Customer" instead of "record").
- Group Screens with a prefix (for example, "Customer_Edit" and "Customer_Show").
- Prefix actions invoked byTimers with "Timer_".
- Set the Name property of ShowRecords, EditRecords and TableRecords.
- Avoid empty labels and descriptions.
- Comment unclear or complex logic.
- Set the example string of Expressions.
- Keep Action Flows vertical and tidy.
- Use Static Entities instead of hard-coded values.
- Reuse logic with User Actions.
- Reuse screen parts with Blocks.
- Encapsulate data formatting with User Functions.
- Use RefreshQuery to rerun a Query.
- Avoid duplicate CSS styles.
- Avoid having hundreds of attributes in one Entity
- Avoid large attributes (e.g. length of 4000)
- Check the Delete Rule of Foreign Keys to an Entity.
- Remember to set the Is Mandatory property.
- Add descriptions at least to the Entities.
Aggregates and Advanced Queries
- Use Aggregates: they’re optimized and database independent!
- Avoid using indexes ([i]) when iterating a Query output.
- Minimize the number of Queries you need to execute.
- Avoid type casts in Aggregates.
- Use Advanced Queries only when absolutely necessary.
- Use Parameters instead of hard-coded values in the SQL.
- Indent SQL code consistently.
- Use comments and inline comments in your SQL.
- Use Advanced Queries for bulk operations.
- Don't put business logic in the SQL.
- Use the EncodeSQL built-in function for Inline Parameters.
- Keep in mind that Advanced Queries are database specific.
Building for change
- Favor Aggregates over Advanced Queries.
- Keep in mind that Advanced Queries are harder to maintain.
- Split functionality in different Web Screens.
- Don’t use Extensions to implement business logic.
- Find out what needs improvement by observing your users.
- Reduce the size of the images in your module.
Use a 3 layers approach:
- Business Processes: a service available for use by users or business processes.
- Core Entities: logical grouping of operations per responsibility.
- Connectors: extensions or integration with other systems.
- Wrap Extensions in modules.
- Avoid circular references between modules.
- Clearly define the responsibilities of each module.
- Remove unused references.
- Encapsulate business logic in User Actions.
- Create user story driven interfaces.
- Don't isolate the data model in one module. Modules should be functional units instead of architectural units.
- Use asynchronous logic when possible.
- Know the recommended project team for your project (see The Talent Playbooks).
- Use a single user for each team member.
- Everyone in the team should use the same Service Studio version.
- Use LifeTime to perform application versioning.
- Avoid publishing single modules: use LifeTime.
- Avoid applying a hotfix without testing it first (see Apply a Hotfix).
- Avoid working on the same elements at the same time.
- Avoid deploying to Production during business hours.
- Create team processes for active log monitoring.
- Create team processes for manual deployment procedures such as data update scripts.
- Define what "done" means and include testing.
Logic and development
- Remove unused or duplicate code.
- A module with a size larger than 4 MB could indicate poor architecture (see How to reduce the size of my eSpace).
- Set at least one default button in your Web Screens.
- Avoid changing Site Properties values in your logic.
- Be careful about infinite recursion.
- Hide warnings only for a good reason.
- More than 20 site properties in one module normally means bad design.
- Avoid using Extensions solely for Web Service consumption.
- Disable auditing of Extensions in Production.
- Set the Web Screen's Roles.
- Be aware of sensitive data exchange.
- Don't send sensitive information in screen parameters.
- Remember: Web Screen's variables or Preparation outputs might be exposed in the URL or Viewstate.
- When applicable, use SSL for sensitive information.
- Don't rely on the Web Screen widgets interface to control permissions.
- Validate user’s Roles before executing Screen Actions.
- Use encrypted passwords in the database.
- Use Internal Access Only for Web Flows and Web Services.
- Index your Entities.
- Isolate large Text and Binary Data in another entity.
- Beware of Large Excel Files Performance.
- Make good use of the Delete Rules in Entities.
- Archive old data in separate Entities.
- Setup database maintenance plans.
- Configure Web server memory settings.
- Backup database transaction logs often.
- Tune database file growth.
- Apply virtual memory and system settings.
- Use a dedicated server for Timers.
- Prefer 64-bit architectures.
- Plan and monitor timers schedule so there are no conflicting schedules.
- Look into Service Center reports.
- Avoid long-running Timers and batch jobs.
- Simplify screen Preparations.
- Place as little information as possible in Session Variables.
- Avoid using isolated Aggregates in User Actions.
- Avoid using queries inside If branches in Preparation.
- Avoid chained Web Service calls. Return as much as possible in a single call.
- Don’t perform joins over linked servers.
- Minimize the number of fields fetched from the database.
- Keep Max Records consistent with your needs.
- Iterate over queries once and avoid using indexes ([i]).
- Minimize the number of executed queries.
- Never create circular references between modules.
- Choose wisely between Local Web Services or Public Actions.
- Use Connection Pooling.
- Avoid using Preparation data in screen actions.
- Use multiple Web Screens instead of creating complex ones.
- Cache, baby, cache!
- Minimize Screen Parameters.
- Use CSS Sprite Images.
Common patterns and examples
Here’s a quick list of several open source apps you can use or refer to for examples:
- Hierarchical tree example: Directory
- Tags implementation example: Documents
- Storing files (binary data) example: Documents
- Inline table editing: Expenses
- Google Maps: Expenses
- Yearly Calendar: Time Sheets
- Charts: Sales
- Using Email POP: Cases
For downloading components to speed up your development time, check out the Forge.
For more learning resources, check the OutSystems Training area.