Best Practices
This guide explores best practices for building applications with Operandi, keeping things simple and effective.
Create Top-Level Services
Creating top-level services for your application is highly recommended. This approach helps keep your services small and focused on a single task.
Application Service
ApplicationService serves as the base class for all services in your application. Use it to place common methods, helpers, context arguments, etc. Remember, it should not contain any business logic.
Create, Update, and Destroy Services
Since create, update, and destroy are fundamental operations in any application, having dedicated services for them is a good idea. This keeps important tasks like authorization, data sanitization, and WebSocket broadcasts close to the core of your application.
CreateRecordService- for creating recordsUpdateRecordService- for updating recordsDestroyRecordService- for destroying records
Think of these services as wrappers around the ActiveRecord::Base#create, #update, and #destroy methods.
Read Services
Similar to the above services but focused on finding records. Use these for generic authorization, filtering, sorting, pagination, etc.
FindRecordService- for finding a single recordFindAllRecordsService- for finding multiple records
Avoid Defining Context Arguments Outside Top-Level Services
Using context arguments outside of top-level services can make your services less modular and more unpredictable. Keep them within the core services for better modularity.
Keep Services Small
Aim to keep your services small and focused on a single task. Ideally, a service should have no more than 3-5 steps. If a service has more steps, consider splitting it into multiple services.
Passing Arguments from Controllers
It's a good practice to create a wrapper method to extend arguments passed to the service from the controller.
Consider this example controller:
Manually passing current_user and current_organization each time can be cumbersome. Let's simplify it with a helper method in our ApplicationController:
Now we can refactor our controller:
With this setup, adding a new top-level context argument only requires a change to the service_args method in ApplicationController.
Use Concerns
If you have common logic that you want to share between services, use concerns. Avoid putting too much logic into your ApplicationService class; it's better to split it into concerns.
For example, create an AuthorizeUser concern for authorization logic.
What's Next?
Explore practical recipes for common patterns:
Last updated