Services Are Not Your Business Layer (And Why That Mistake Scales Poorly)
The Angular Service That Started Innocently
Services Are Not Your Business Layer (And Why That Mistake Scales Poorly)
The Angular Service That Started Innocently

Most Angular services begin their life looking something like this:
@Injectable()
export class CustomerService {
constructor(
private http: HttpClient
) {}
getCustomers() {
return this.http.get<Customer[]>(
'/api/customers'
);
}
}
Simple.
Clean.
Easy to understand.
The service acts as a thin wrapper around an API.
Nothing controversial.
Then the application grows.
And that’s when things begin to change.
**Not a Member? Read for FREE here.**
The Slippery Slope
A new requirement arrives.
The customer data needs validation.
So validation gets added.
Then permissions.
Then audit logging.
Then caching.
Then analytics.
Then feature flags.
Then approval workflows.
Eventually the service looks like this:
@Injectable()
export class CustomerService {
validateCustomer() {}
checkPermissions() {}
calculateDiscounts() {}
determineApprovalFlow() {}
logAuditEvent() {}
updateCache() {}
sendAnalytics() {}
notifyUsers() {}
saveCustomer() {}
}
The service is no longer a service.
It’s an entire application hidden inside a single file.
Why This Happens
Angular gives us a convenient place to put logic.
That place is called a service.
So whenever developers ask:
Where should this code go?
The answer often becomes:
Put it in the service.
Repeat this enough times and the service becomes the default destination for everything.
The architecture slowly collapses into:
Component
│
▼
Huge Service
│
▼
Everything Else
At first this feels organized.
Eventually it becomes one of the biggest maintenance problems in the codebase.
Services Were Never Meant To Own Business Logic
This is the key misunderstanding.
A service is not a business layer.
A service is simply a technical abstraction.
Examples:
CustomerApiService
NotificationService
StorageService
AnalyticsService
LoggingService
Notice something.
Each service performs a technical responsibility.
They provide capabilities.
They don’t define business processes.
That’s an important distinction.
Business Logic Is Different
Consider a customer approval workflow.
The workflow might be:
Validate Customer
│
▼
Check Permissions
│
▼
Determine Approval Level
│
▼
Save Customer
│
▼
Generate Audit Record
This is not a technical concern.
This is business behavior.
The workflow exists regardless of:
- Angular
- APIs
- Databases
- Frameworks
Business logic describes how the business operates.
Not how software communicates.
The Problem With God Services
Imagine a service growing for three years.
Ten developers contribute.
New requirements continuously arrive.
Soon the service becomes:
CustomerService
├── API Calls
├── Validation
├── Permissions
├── Workflow Rules
├── State Updates
├── Analytics
├── Logging
├── Notifications
├── Cache Updates
└── Feature Flags
Now every feature touches the same file.
Merge conflicts increase.
Testing becomes harder.
Understanding behavior becomes difficult.
Changing one workflow risks breaking another.
The service becomes a bottleneck.
What Scalable Architectures Do Instead
Large applications separate responsibilities.
Example:
CustomerPageComponent
│
▼
CustomerFacade
│
▼
CustomerApprovalWorkflow
│
├── CustomerApiService
├── AuditService
├── NotificationService
└── PermissionService
Each layer has a specific responsibility.
Components coordinate.
Workflows define business behavior.
Services provide technical capabilities.
The architecture becomes easier to evolve.
A Useful Mental Model
Think of services as tools.
A hammer is useful.
A screwdriver is useful.
A wrench is useful.
But none of those tools define how to build a house.
Similarly:
NotificationService
LoggingService
AnalyticsService
are tools.
They help implement business processes.
They are not the business process itself.
The Facade Layer Changes Everything
Many enterprise Angular applications introduce facades.
Instead of:
Component
│
▼
Huge Service
You get:
Component
│
▼
Facade
│
▼
Workflow Layer
│
▼
Services
This creates a natural separation.
Business decisions stay together.
Technical implementations stay together.
Future changes become easier.
Signals Don’t Solve This Problem
Modern Angular gives us Signals.
Signals simplify state management.
Signals improve reactivity.
Signals reduce boilerplate.
But Signals do not solve misplaced responsibilities.
You can still build a 3,000-line service using Signals.
The underlying architectural mistake remains the same.
Architecture and reactivity solve different problems.
How To Spot A Service That Has Become Too Large
Warning signs include:
- Hundreds of lines of business rules
- Multiple unrelated responsibilities
- Large constructor dependency lists
- Difficult unit tests
- Frequent merge conflicts
- Developers afraid to modify it
When these symptoms appear, the service has likely outgrown its original purpose.
What Senior Engineers Usually Ask
Junior developers often ask:
Where should I put this code?
Senior engineers ask:
Who should own this responsibility?
That question changes everything.
Instead of dumping logic into services, they think about:
- Business boundaries
- Ownership
- Workflows
- Dependencies
- Long-term maintainability
This leads to much healthier architectures.
A Practical Rule
Whenever you’re about to add new logic to a service, ask:
Is this technical behavior or business behavior?
If it’s technical:
A service is probably appropriate.
If it’s business behavior:
Consider a workflow layer, facade, store, or domain abstraction.
That small distinction prevents many architectural problems.
Final Thoughts
Angular services are one of the framework’s most useful features.
Unfortunately, they often become victims of their own convenience.
Because services provide an easy place to put code, teams gradually place too much code inside them.
The result is the infamous God Service.
The best Angular architectures treat services as technical capabilities.
Business workflows live elsewhere.
Responsibilities remain clear.
And maintainability remains manageable long after the application has grown.
The goal isn’t to eliminate services.
The goal is to stop asking services to do everything.
Connect with Me
If you enjoyed this post and would like to stay updated with more content like this, feel free to connect with me on social media:
- Twitter : Follow me on Twitter for quick tips and updates.
- LinkedIn : Connect with me on LinkedIn
- YouTube : Subscribe to my YouTube Channel for video tutorials and live coding sessions.
- Dev.to : Follow me on Dev.to where I share more technical articles and insights.
- WhatsApp : Join my WhatsApp group to get instant notifications and chat about the latest in tech
Email: Email me on dipaksahirav@gmail.com for any questions, collaborations, or just to say hi!
I appreciate your support and look forward to connecting with you!
메타데이터
- post_id
- 08c6787d1649
- slug
- services-are-not-your-business-layer-and-why-that-mistake-scales-poorly-08c6787d1649
- url
- https://medium.com/angular-engineering/services-are-not-your-business-layer-and-why-that-mistake-scales-poorly-08c6787d1649
- canonical_url
- https://medium.com/angular-engineering/services-are-not-your-business-layer-and-why-that-mistake-scales-poorly-08c6787d1649
- author_url
- https://medium.com/@dipaksahirav
- status
- ok
- fetched_at
- 2026-06-14 11:28:49