Skip to main content
Services in Orionjs encapsulate business logic, following the dependency injection pattern to make your code more modular, testable, and maintainable. They separate business logic from data access and controllers.

Structure and Naming

  • Use @Service() decorator from @orion-js/services
  • Each service should focus on a single business operation
  • Follow verb-noun naming convention: {Action}{Entity}Service (e.g., SendEmailService, CreatePostService, CallWebhookService)
  • Service should typically have one main public method named like the action (e.g., execute, send, create)
  • Put services in app/{component}/services/{Action}{Entity}/index.ts

Best Practices

  • Single Responsibility: One service should do only one thing
  • Meaningful Business Logic: Services should contain meaningful business logic, not just pass-through to repositories
  • Don’t Over-Abstract: Don’t create services for simple repository interactions - call repositories directly from controllers or other services
  • Keep Methods Short: Divide logic into private methods within the same service
  • Use repositories for database operations
  • Use dependency injection with @Inject(() => ServiceName)
  • Add proper typing for all parameters and return values
  • Handle validation and error cases appropriately
  • Prefer throwing ValidationError when validation of data fails
  • Prefer throwing UserError when the error is not a system error

Basic Example

Here’s an example of a service that implements a single business operation with meaningful business logic:

Complex Service Example

A more complex example showing a service that orchestrates multiple operations:

Dependency Injection

Services can be injected into other services or controllers. Always use the factory function pattern:
The factory function pattern @Inject(() => ServiceName) automatically handles circular dependencies.

Getting Service Instances

You can get service instances from anywhere in your application:

Testing

Services are designed to be easily testable with mocks:

When NOT to Create a Service

Don’t create a service if you’re just:
  • Calling a single repository method without additional business logic
  • Passing through data without transformation or validation
  • Creating a thin wrapper around an external API without business rules
In these cases, call the repository or external service directly from your controller or another service.