Philosophy

In Exowpee, controllers handle HTTP and services handle business logic. This separation makes the code easier to test, reuse, and maintain.

Convention

Service classes follow these rules:
  1. Naming: {Domain}Service — e.g., ProductService, OrderService, AuthService
  2. Location: packages/{name}/src/Services/
  3. Public methods first: Public methods (called by controllers) are always above private methods (internal helpers)
  4. Services per sub-domain: Complex packages have multiple services split by sub-resource (e.g., ProductService, ProductVariantService, ProductImageService, CategoryService)
  5. Injected via constructor: Services are resolved from Laravel’s container

Example: ProductService

Services per package

When to use a service vs. a controller

Controller + Service pattern

Testing services

Services can be tested independently of HTTP: