Skip to content

Commit f26f7bb

Browse files
committed
feat: add services docs
1 parent 611a8c0 commit f26f7bb

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

.vitepress/config/sidebar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ const sidebar = [
176176
// { text: 'Migrations', link: '/docs/database/migrations' },
177177
// { text: 'JSON Schema', link: '/docs/database/schema' },
178178
{ text: 'Schema Files', link: '/docs/database/files' },
179-
// { text: 'Seeders', link: '/docs/database/seeders' },
179+
{ text: 'Services', link: '/docs/mvc/services' },
180180
// { text: 'Factories', link: '/docs/database/factories' },
181181
{ text: 'Writing Commands', link: '/docs/mvc/commands' },
182182
// { text: 'Mailing', link: '/docs/utils/mail/mvc' },

src/docs/mvc/services.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<!-- markdownlint-disable no-inline-html -->
2+
3+
# Services <Badge>New</Badge>
4+
5+
Services let you encapsulate business logic and make it reusable across your application. For example, you might have functionality in `StatsController` that you want to use in `DashboardController` or expose via an API. Instead of duplicating code, you can create a service class and inject it where needed.
6+
7+
## Creating a Service
8+
9+
Services are just plain PHP classes — no base class or interface required. By convention, we keep them in `app/services`, but you can place them anywhere in your project. Let's create our `StatsService` from the earlier example:
10+
11+
```php
12+
<?php
13+
14+
namespace App\Services;
15+
16+
class StatsService
17+
{
18+
public function getDashboardData()
19+
{
20+
return [
21+
'users' => 1500,
22+
'sales' => 2300,
23+
'revenue' => 12000,
24+
];
25+
}
26+
}
27+
```
28+
29+
That's it! A service doesn't have to extend any base class or implement any interface. It's simply a class that contains methods for your business logic.
30+
31+
## Using a Service
32+
33+
To use a service in a controller, you simply call `make()` to resolve it from anywhere in your application. Here's how you can use the `StatsService` in a `DashboardController`:
34+
35+
```php{11}
36+
<?php
37+
38+
use App\Services\StatsService;
39+
40+
class DashboardController extends Controller
41+
{
42+
public function index()
43+
{
44+
return response()->inertia(
45+
'dashboard',
46+
make(StatsService::class)->getDashboardData()
47+
);
48+
}
49+
}
50+
```
51+
52+
::: tip Why `make()`?
53+
54+
In this version of Leaf, `make()` simply initializes the service class just like calling `new`, but future versions of Leaf may expand its behavior, so we encourage always using `make()` instead of initializing classes directly.
55+
56+
:::
57+
58+
## Why no dependency Injection?
59+
60+
If you’re coming from frameworks like Laravel, you might expect to inject services through constructors or method injection. While this is powerful, it also adds extra complexity.
61+
62+
In Leaf, almost everything you need is already accessible through global functions, so there’s no need to inject dependencies just to use them. To keep things simple and consistent, Leaf uses make() to resolve services.
63+
64+
Instead of wiring dependencies into constructors, you can simply call a function (`make()`, `cache()`, `response()`, etc.) to get what you need — anywhere in your app.
65+
66+
## When to Use a Service
67+
68+
- When you have reusable business logic (e.g. stats, billing, reporting).
69+
70+
- When same logic would otherwise live in multiple controllers.
71+
72+
- When you want to keep controllers thin and focused on handling requests, not doing the heavy lifting.

0 commit comments

Comments
 (0)