转自 PHP / Laravel 开发者社区 https://laravel-china.org/topics/21913

我非常喜欢编写基于模块化设计的软件和编程方式,但我不太喜欢依赖第三方软件包和类库来处理一些琐碎的事情,因为它们不会让你的编程水平得到很好的提升。所以这两年来,我一直在用Laravel编写基于模块的软件,现在我对这个结果非常满意。

推动我走向基于模块化设计的软件和编程方式的决定性因素是我想持续提升我的编程水平。想象一下,你构建了一个项目结构,6个月后你发现这个项目存在很多bug。在不影响6个月现有代码的情况下,通常不会轻易改变项目架构。在分析这个项目时,我注意到了两个要点:你要么在整个项目中都有一个标准,要么坚持下去,要么模块化并逐个模块地改进。

有些人倾向于不惜一切代价、固守标准地开发,即使这可能意味着要坚持一个你不再喜欢的标准。就我个人来言,我更喜欢持续地改进,若是第 20 个模块和第 1 个模块写得完全不一样也没关系。如果某天我需要回到模块 1 修复 BUG 或重构,我可以将其改进为第 20 个模块使用的最新标准。

假设,你也像我一样喜欢基于模块化开发 Laravel 应用、尽可能避免在项目中添加不必要的第三方依赖——本文是我的一点经验。

1- 路由服务提供者

Laravel 路由系统可以说是整个应用的入口。首先需要修改的是默认的 RouteServiceProvider.php 文件,它应当将现有路由模块化。

<?php
namespace AppProviders;
use IlluminateSupportFacadesRoute;
use IlluminateFoundationSupportProvidersRouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{/*** 定义应用路由。** @return void*/public function map(){$this->mapModulesRoutes();}protected function mapModulesRoutes(){// 如果你在编写传统 Web 应用而非 HTTP API,请使用 `web` 中间件。 Route::middleware('api')->group(base_path('routes/modules.php'));}
}

如上,我们可以直接摆脱该文件的整个样板,只需设置一个模块化的路由文件即可。

2- 模块文件

Laravel 在 routes 文件夹中自带了一些文件。由于我们已经不在 RouteServiceProvider 中映射这些路由,所以可以直接删除它们。接下来,我们创建一个 modules.php 路由文件。

<?php
use IlluminateSupportFacadesRoute;
Route::group([], base_path('app/Modules/Books/routes.php'));
Route::group([], base_path('app/Modules/Authors/routes.php'));

3- Books 模块

app 文件夹中,创建 Modules/Books/routes.php 文件。在此文件中,我们可以定义该应用 Books 模块的路由规则。

<?php
use AppModulesBooksListBooks;
use IlluminateSupportFacadesRoute;
Route::get('/books', ListBooks::class);

你可以使用基于控制器——也就是 Laravel 中默认标准的路由方式,但我个人更喜欢 Good bye controllers, hello Request Handlers(放弃控制器,采用请求处理器) 的方式。 如下是 ListBooks 的实现。

<?php
namespace AppModulesBooks;
use AppEloquentBook;
use AppModulesBooksResourcesBookResource;
class ListBooks
{public function __invoke(Book $book){return BookResource::collection($book->paginate());}
}

以上代码中 BookResource 是 Laravel 的资源转换层。按照官方对于命名空间的建议,我们可以在 app/Modules/Books/Resources 文件夹中创建它。

<?php
namespace AppModulesBooksResources;
use IlluminateHttpResourcesJsonResource;
class BookResource extends Resource
{public function toArray($request){return ['id' => $this->resource->id,'title' => $this->resource->title,];}
}

4- Authors 模块

我们还可以通过 Routes 文件来启动 Authors 模块。

<?php
use AppModulesAuthorsListAuthors;
use IlluminateSupportFacadesRoute;
Route::get('/authors', ListAuthors::class);

注意: app/Modules/Authors 这个命名空间正表示我们所编写的文件,对于请求处理程序来说也是非常简单的。

<?php
namespace AppModulesAuthors;
use AppEloquentAuthor;
use AppModulesAuthorsResourcesAuthorResource;
class ListAuthors
{public function __invoke(Author $author){return AuthorResource::collection($author->paginate());}
}

最后,我们将编写的 Resource 类转变为响应式的 JSON 格式。

<?php
namespace AppModulesAuthorsResources;
use AppModulesBooksResourcesBookResource;
use IlluminateHttpResourcesJsonResource;
class AuthorResource extends Resource
{public function toArray($request){return ['id' => $this->resource->id,'name' => $this->resource->name,'books' => $this->whenLoaded('books', function () {return BookResource::collection($this->resource->books);})];}
}

注意资源是如何进入另一个模块以重用 BookResource 。 这通常不是一个比较好的选择,因为模块应该是完全自给自足的,并且只能重用标准类,例如 Eloquent Models 或设计用于在任何模块上通用的通用的组件。 这个问题的解决方案通常是将 BookResource 复制到 Authors 模块中,从而可以在不使用另一个模块的情况下进行更改,反之亦然。 我决定保留这个跨模块的用法,这个例子表现出一个很好的经验方法,就是让模块之间彼此隔离,但是如果你认为上面的例子很简单并且不太可能带来任何问题。 始终确保编写测试以涵盖您编写的功能,以避免其他人在不知不觉中修改您的应用程序。

5- 结语

虽然这是一个非常简单的例子,但我希望它能够让人们根据自己的需要来轻松操作使用 Laravel 框架的结构标准。您可以非常轻松地更改文件的位置,以便构建基于模块化的应用程序。我的大多数项目都附带了 App / Components 模块,可以适用于任何模块可重用的泛类型的基础类; App / EloquentModules 文件夹可以用于保存 Eloquent 模型和数据库关系模型,我们可以在其中构建任何基于模块化的功能。 这是我最近开始研究的应用程序的文件夹目录结构:

我希望每个人都能从中得到这个概念,每个模块都有自己的需求,并且可以拥有自己的文件夹/实体/类/方法/属性。没有必要将所有模块标准化完全相同,因为某些模块比其他模块简单得多,并且不需要大量的结构设计。此示例显示AccountChurn模块通过 HTTP 文件夹提供 API,同时仍通过控制台提供 Artisan 命令。另一方面,AccountOverview则仅提供 HTTP API,并且依赖仓库、值对象(bags)以及服务类(paginators)来提供更大的数据价值。

laravel架构判断id存在与否 存在进行什么操作_基于 Module 的 Laravel API 架构相关推荐

  1. 基于 Module 的 Laravel API 架构

    转自 PHP / Laravel 开发者社区 https://laravel-china.org/top... 我非常喜欢编写基于模块化设计的软件和编程方式,但我不太喜欢依赖第三方软件包和类库来处理一 ...

  2. 基于linux的贪吃蛇游戏设计_基于ECS的游戏引擎架构设计「译」

    摘要 游戏编程设计和组织是困难而复杂的,为了简化开发进程,会使用被称为游戏引擎的游戏框架(framework),该框架包含了一组实用工具.本项的目的是探索游戏引擎设计和开发一个模块化和可扩展的游戏引擎 ...

  3. 基于.NET平台的分层架构实战(二)——需求分析与数据库设计

    基于.NET平台的分层架构实战(五)--接口的设计与实现 · 基于.NET平台的分层架构实战(四)--实体类的设计与实现 · 基于.NET平台的分层架构实战(三)--架构概要设计 · 基于.NET平台 ...

  4. python前端调用后端模型_前端调用后端的方法(基于restful接口的mvc架构)

    1.前端调用后台: 建议用你熟悉的一门服务端程序,例如ASP,PHP,JSP,C#这些都可以,然后把需要的数据从数据库中获得,回传给客户端浏览器(其实一般就是写到HTML中,或者生成XML文件)然后在 ...

  5. php id 生产器,Laravel 分布式唯一 ID 生成器运用_PHP开发框架教程

    在运用程序中,常常须要全局唯一的ID作为数据库主键.怎样生成全局唯一ID? 起首,须要肯定全局唯一ID是整型照样字符串?假如是字符串,那末现有的UUID就完整满足需求,不须要分外的事情.瑕玷是字符串作 ...

  6. 基于 Docker 的微服务架构实践

    http://dockone.io/article/4887 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 DevOps,也见证了 Do ...

  7. docker容器 eureka 集成_微服务:基于 Docker 的微服务架构之分布式企业级实践参考...

    编者按:本文分享自CSDN技术博客,作者为 FlyWine,所有权归原著者.若有不妥,联系本头条号以做必要处理. 目录 Microservice 和 Docker 服务发现模式 客户端发现模式 Net ...

  8. 基于 Docker 的微服务架构

    基于 Docker 的微服务架构-分布式企业级实践 前言 Microservice 和 Docker 服务发现模式 客户端发现模式 Netflix-Eureka 服务端发现模式 Consul Etcd ...

  9. 基于CSE的微服务架构实践-轻量级架构技术选型

    [摘要] 本文在前一篇"基于CSE的微服务架构实践-基础架构"基础上,介绍了使用CSE进行轻量级架构的技术选型参考.文末提供了基于JWT的微服务认证鉴权方案. 轻量级架构模式下,可 ...

最新文章

  1. 运维监控利器Nagios:概念、结构和功能
  2. 直接内存访问(DMA)
  3. 数学--数论---P4718 Pollard-Rho算法 大数分解
  4. html新建通用loading,漂亮实用的页面loading(加载)封装代码
  5. Eclipse用法和技巧五:生成说明文档2
  6. 《Genesis-3D游戏引擎系列教程-进阶篇》10:动画融合
  7. SqlServer 存贮过程操作类
  8. linux查询进程命令stap,linux systemtap, stap++使用
  9. 运维工程师可能遇到的面试题
  10. 常见bugger集合
  11. 高级运维工程师面试题(更新中)
  12. 微信小程序合并单元格
  13. 21年 河海大学 计算机科学与技术(838) 学硕 上岸心得
  14. Siri触发器原理及改进
  15. 华清远见上海中心22071班 9.30作业
  16. 巨头身影已现、赢家纷纷上市,金融科技市场还有创业者的机会吗?
  17. Hdu 3666(差分约束系统)
  18. QT核心机制3:信号与槽
  19. Google地图API方式查看卫星地图
  20. 轮式移动机器人的运动控制入门

热门文章

  1. 您的用户账户没有连接到http://192.168.0.112:8080/tfs上的team foundation server的权限
  2. 无心插柳,再次浅谈.net资源的回收
  3. php mysql bbs_BBS(php mysql)完整版(二)
  4. Glib2之无法添加符号: DSO missing from command line(十九)
  5. Ubuntu18.04上AS运行模拟器报错:/dev/kvm device: permission denied
  6. tensorflow之random_normal
  7. educoder MongoDB 数据库基本操作
  8. XP系统访问win7共享文件夹教程和提示没有权限的解决办法
  9. 利用vuex和localStorage实现vue菜单权限管理(笔记)
  10. python刷今日头条阅读量_教你如何提高今日头条号推荐量阅读量播放量