Services
Services in Medusa encapsulate business logic and data access. They follow the MedusaService pattern, which provides automatic transaction management, event emission, and context injection through decorators.MedusaService Pattern
All module services extendMedusaService, which provides:
- Automatic CRUD operations - Generated list, retrieve, create, update, delete methods
- Transaction management - Decorators for database transactions
- Event emission - Automatic domain event publishing
- Context injection - Shared context across operations
- Type safety - Strongly typed DTOs and entities
The MedusaService pattern standardizes how services are built across all Medusa modules, ensuring consistency and reducing boilerplate.
Creating a Service
Basic Service Structure
packages/modules/api-key/src/services/api-key-module-service.ts:44-67
Service Type Definitions
Define entity-to-DTO mappings in the generic:packages/modules/product/src/services/product-module-service.ts:82-120
Service Decorators
Medusa provides four key decorators for cross-cutting concerns:@InjectManager
Injects an entity manager for database operations. Use on public methods.@InjectTransactionManager
Injects a transaction manager for atomic operations. Use on protected methods.packages/modules/api-key/src/services/api-key-module-service.ts:69-110
@MedusaContext
Injects shared context into the decorated parameter. Always use as the last parameter.The
@MedusaContext() decorator must always be applied to the last parameter of the method, and that parameter should default to an empty object {}.@EmitEvents
Automatically emits domain events after the method completes successfully.packages/modules/api-key/src/services/api-key-module-service.ts:123-150
Events are automatically emitted based on the entity name and operation:
apiKey.created- After creating API keysapiKey.updated- After updating API keysapiKey.deleted- After deleting API keys
Decorator Combinations
Common decorator patterns:Transaction Management
Services handle transactions automatically through decorators:Automatic Transactions
Manual Transactions
For complex scenarios, manually manage transactions:Event Emission
Services emit events automatically with@EmitEvents:
Automatic Event Names
Events follow the pattern{entityName}.{operation}:
Event Data
Event data includes the entity IDs:Subscribing to Service Events
Create subscribers to handle service events:Context Propagation
The shared context flows through all service calls:Custom Context Data
Add custom data to the context:Error Handling
Services useMedusaError for consistent error handling:
Common Error Types
packages/modules/api-key/src/services/api-key-module-service.ts:100-107
Best Practices
1
Use Public/Protected Pattern
Public methods have
@InjectManager and @EmitEvents. Protected methods (suffixed with _) have @InjectTransactionManager.2
Always Pass Context
Always pass
sharedContext to nested service calls to maintain transaction scope.3
Validate Early
Validate input data before starting database operations to fail fast.
4
Return Serialized DTOs
Use
baseRepository_.serialize() to return properly typed DTOs.Testing Services
Services are testable through dependency injection:Next Steps
Events
Learn how to subscribe to service events
Workflows
Use services in workflow steps