lucid-arch / laravel-microservice
使用Lucid架构实现的Laravel框架 - 作为微服务。
Requires
- php: ^7.3
- fideloper/proxy: ^4.2
- fruitcake/laravel-cors: ^1.0
- guzzlehttp/guzzle: ^7.0.1
- laravel/framework: ^8.0
- laravel/tinker: ^2.0
- lucid-arch/laravel-foundation: ^8.0
Requires (Dev)
- facade/ignition: ^2.3.6
- fzaninotto/faker: ^1.9.1
- lucid-arch/laravel-console: ^7.0
- mockery/mockery: ^1.3.1
- nunomaduro/collision: ^5.0
- phpunit/phpunit: ^9.0
README
随着按关注点分离的需求日益增长,微服务应运而生,成为原本单体应用的流行发展趋势。特别是在Lucid架构中,可扩展性是微服务架构从其单体对应架构的自然演进。
Lucid单体应用的不同部分被称为服务并非巧合,因为当应用规模扩大并达到转折点时,微服务确实是其自然演进。使用Lucid实现您的应用程序后,过渡过程将更容易从逻辑上思考,在物理上实施也将更为直接。
要了解它与单体应用的比较以及何时使用哪种,请查看单体与微服务
在Slack加入社区
构建可扩展应用的Lucid架构 - Laracon EU 2016
查看我在LaraconEU 2016的演讲,其中介绍了Lucid架构的概念和应用:
安装
要开始,您需要使用Composer创建一个新项目
composer create-project lucid-arch/laravel-microservice my-project
入门
该项目包含Lucid Console,它提供了一个交互式用户界面和命令行界面,这些界面对于脚手架和服务、功能和工作任务的探索非常有用。
设置
lucid
可执行文件将在vendor/bin
中。如果您没有将./vendor/bin/
作为您的PATH
的一部分,您将需要使用./vendor/bin/lucid
来执行它,否则可以使用以下命令添加它,以便能够简单地调用lucid
export PATH="./vendor/bin:$PATH"
要查看所有可用的命令列表,请运行lucid
或查看CLI参考。
1. 创建功能
这是我们将在有人访问我们的/users
路由时提供的服务。
lucid make:feature ListUsers
2. 创建作业
此任务将从数据库中检索用户,并在我们的功能内部使用。
lucid make:job GetUsers user
打开位于 app/Domains/User/GetUsersJob.php
的文件,并编辑 handle
方法为以下内容
public function handle() { return [ ['name' => 'John Doe'], ['name' => 'Jane Doe'], ['name' => 'Tommy Atkins'], ]; }
在实际应用中,您可能希望从数据库中检索用户,这里正是合适的位置。以下是一个检索用户列表并提供指定限制的示例
use App\Data\Models\User; class GetUsersJob extends Job { private $limit; public function __construct($limit = 25) { $this->limit = $limit; } public function handle(User $user) { return $user->take($this->limit)->get(); } }
注意:模型命名空间为
[app 命名空间]\Data\Models
3. 运行任务
// ... use App\Domains\User\GetUsersJob; use App\Domains\Http\RespondWithJsonJob; // ... public function handle(Request $request) { $users = $this->run(GetUsersJob::class); return $this->run(new RespondWithJsonJob($users)); }
RespondWithJsonJob
是本项目附带的任务之一,它位于 Http
域,用于以结构化 JSON 格式响应请求。
4. 提供功能服务
为了能够提供该功能,我们需要创建一个路由和一个控制器来实现。
使用以下命令生成一个普通控制器
lucid make:controller user
然后,我们将生成位于 app/Http/Controllers/UserController.php
的 UserController
,我们将使用它在其 index
方法中提供服务。
我们只需要创建一个将请求委派给我们的 index
方法的路由
// ... use App\Features\ListUsersFeature; // ... class UserController extends Controller { public function index() { return $this->serve(ListUsersFeature::class); } }
在 routes/web.php
中添加
Route::get('/users', 'UserController@index');
就这样!现在使用 php artisan serve
运行应用程序,并访问 http://localhost:8000/users
事件钩子
Lucid 提供了事件钩子,允许您监听每个分发的功能、操作或任务。这对于跟踪特别有用
use Illuminate\Support\Facades\Event; use Lucid\Foundation\Events\FeatureStarted; use Lucid\Foundation\Events\OperationStarted; use Lucid\Foundation\Events\JobStarted; Event::listen(FeatureStarted::class, function (FeatureStarted $event) { // $event->name // $event->arguments }); Event::listen(OperationStarted::class, function (OperationStarted $event) { // $event->name // $event->arguments }); Event::listen(JobStarted::class, function (JobStarted $event) { // $event->name // $event->arguments });
单体应用与微服务
在 Lucid 的单体应用中,我们有多个服务(例如,Api、Web),这些服务通常存在于 src/Services/Api
和 src/Services/Web
中。在微服务中,由于它旨在是一个服务于单一目的的服务,因此不存在 src
,app
目录将用于存放以下目录
- 数据 存放所有的模型、仓库和值对象。
- 域 存放域及其任务。
- 功能 服务的功能。
目录结构
组件 | 单体应用 | 微服务 |
---|---|---|
任务 | src/Domains/[domain]/Jobs/[job] | app/Domains/[domain]/Jobs/[job] |
功能 | src/Services/[service]/Features/[feature] | app/Features/[feature] |
服务 | src/Service/[service] | N/A (app) 作为等效 |
测试
另一个显著的区别是测试的位置
组件 | 单体应用 | 微服务 |
---|---|---|
任务 | src/Domains/[domain]/Tests/Jobs/[JobTest] | tests/Domains/[domain]/Jobs/[JobTest] |
功能 | src/Services/[service]/Tests/Features/[FeatureTest] | tests/Features/[Feature]Test.php |
如何选择
始终建议您从一个单体应用开始,直到它变得如此之大,以至于将其分解为单一用途的服务(微服务)变得至关重要。这将是一个挑战,您可能无法确定应用程序未来的不同服务。
当您确信应用程序将不会处理多个服务,但仍然想使用 Lucid 时,此项目也非常有用。