Core Concepts of the pOS Marketplace Template
The pOS Marketplace Template is a fully functional marketplace built on platformOS with features like user onboarding, ad listings and ads, purchase and checkout process, and online payment. Following the tutorial, you can deploy this code within minutes to have a list of working features and start customizing the back- and front-end code.
This topic describes the core concepts like the business logic, presentation logic, data queries, categories, and tests for the pOS Marketplace Template.
Requirements
To explore the pOS Marketplace Template, follow our Get Started guide to set up your development environment and install the template.
Business logic
General rules
Business logic and presentation logic are separated and should not interfere with each other, meaning:
- no HTML tags in business logic
- no data queries in presentation layer
Commands
Command is our concept to encapsulate business rules. By following our recommendation, you can improve the consistency of your code to make it easier to onboard new developers to the project and take over existing projects. We use the same pattern for all of our templates. The advantage of using this architecture is that it is easy to re-use the command - you can execute it in a live web request as well as a background job. It is also easy to copy it across different projects.
Command are located in app/views/partials/lib/commands
-
For business logic use commands
-
A generic command consists of 3 stages:
- Build: This is the place where you build input for the command; if you are proficient with platformOS - equivalent of
Form
'sdefault_payload
- Validate: This is the place where you validate the input - for example, you ensure all required fields are provided, you check uniqueness, check the format of the input (numbers are really numbers and not letters), etc. This always returns a hash with two keys -
valid
being eithertrue
orfalse
, and iffalse
-errors
with details why validation has failed. - Execute: If validation succeeds, proceed with executing the command. Any error raised here should be considered a 500 server error. If you allow errors here, it means there is something wrong with the code organisation, as all checks to prevent errors should be done in the
validate
step.
- Build: This is the place where you build input for the command; if you are proficient with platformOS - equivalent of
-
Commands are designed to be easily executed as background jobs [heavy commands - external API call, expensive operations computations, reports]
-
Each command might produce an event
Command workflow
This command workflow describes the three stages and validations of a command.
Build
- Security first
- Build object based on preferred command schema
- Collect data from various sources: session, user input, database
- Cast types and convert, for example, string into arrays, string to integer, etc.
- Filter out forbidden parameters from user input
Example: context.exports.object
{
"name": "ObjectName",
"price": null
}
Check
- Validate the object properties data types
- Validate the object against business rules
- User permission check: Can the user edit a specific field?
Example:
{
"name": "ObjectName",
"price": null,
"errors": {
"price": ["app.errors.blank"]
},
"valid": false
}
If the object validation fails:
- the user should correct data soft errors
- render form with error messages
If the object validation succeeds, proceed to the Execute stage.
Execute
Execute command core function, for example:
- Save the object in the database
- Send API request
- Make payment
If the object validation fails:
- Log error
- Notify development team
- Render 500 error
If the object validation succeeds, redirect and notify the user about the successful operation.
Data queries
Data queries are located in app/views/partials/lib/data/queries
- Generally, these are wrappers on GraphQL queries
Events
General
- Each command produces an event
- Example: when a user logs in the system produces the
user_session_created
event, which looks similar to this:{ actor: { id: LOGGED_USER_ID } }
- Then the event can be asynchronously consumed by a consumer
Consumers
Consumers are located in app/views/partials/lib/consumers
.
Categories
Categories management is part of the Admin UI at /admin/categories
.
Performance
Our template adheres to the code quality and performance best practices required for platformOS end client builds. When building a platformOS site, make sure you follow our recommendations and learn more about achieving outstanding performance: