溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Laravel基于Module實(shí)現(xiàn)API架構(gòu)的示例

發(fā)布時(shí)間:2021-01-25 12:27:57 來源:億速云 閱讀:234 作者:小新 欄目:編程語(yǔ)言

這篇文章給大家分享的是有關(guān)Laravel基于Module實(shí)現(xiàn)API架構(gòu)的示例的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

我非常喜歡編寫基于模塊化設(shè)計(jì)的軟件和編程方式,但我不太喜歡依賴第三方軟件包和類庫(kù)來處理一些瑣碎的事情,因?yàn)樗鼈儾粫?huì)讓你的編程水平得到很好的提升。所以這兩年來,我一直在用 Laravel 編寫基于模塊的軟件,現(xiàn)在我對(duì)這個(gè)結(jié)果非常滿意。

推動(dòng)我走向基于模塊化設(shè)計(jì)的軟件和編程方式的決定性因素是我想持續(xù)提升我的編程水平。想象一下,你構(gòu)建了一個(gè)項(xiàng)目結(jié)構(gòu),6 個(gè)月后你發(fā)現(xiàn)這個(gè)項(xiàng)目存在很多 bug。在不影響 6 個(gè)月現(xiàn)有代碼的情況下,通常不會(huì)輕易改變項(xiàng)目架構(gòu)。在分析這個(gè)項(xiàng)目時(shí),我注意到了兩個(gè)要點(diǎn):你要么在整個(gè)項(xiàng)目中都有一個(gè)標(biāo)準(zhǔn),要么堅(jiān)持下去,要么模塊化并逐個(gè)模塊地改進(jìn)。

有些人傾向于不惜一切代價(jià)、固守標(biāo)準(zhǔn)地開發(fā),即使這可能意味著要堅(jiān)持一個(gè)你不再喜歡的標(biāo)準(zhǔn)。就我個(gè)人來言,我更喜歡持續(xù)地改進(jìn),若是第 20 個(gè)模塊和第 1 個(gè)模塊寫得完全不一樣也沒關(guān)系。如果某天我需要回到模塊 1 修復(fù) BUG 或重構(gòu),我可以將其改進(jìn)為第 20 個(gè)模塊使用的最新標(biāo)準(zhǔn)。

假設(shè),你也像我一樣喜歡基于模塊化開發(fā) Laravel 應(yīng)用、盡可能避免在項(xiàng)目中添加不必要的第三方依賴 —— 本文是我的一點(diǎn)經(jīng)驗(yàn)。

1- 路由服務(wù)提供者

Laravel 路由系統(tǒng)可以說是整個(gè)應(yīng)用的入口。首先需要修改的是默認(rèn)的 RouteServiceProvider.php 文件,它應(yīng)當(dāng)將現(xiàn)有路由模塊化。

<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
    /**
     * 定義應(yīng)用路由。
     *
     * @return void
     */
    public function map()
    {
        $this->mapModulesRoutes();
    }
    protected function mapModulesRoutes()
    {
        // 如果你在編寫傳統(tǒng) Web 應(yīng)用而非 HTTP API,請(qǐng)使用 `web` 中間件。 
        Route::middleware('api')
             ->group(base_path('routes/modules.php'));
    }
}

如上,我們可以直接擺脫該文件的整個(gè)樣板,只需設(shè)置一個(gè)模塊化的路由文件即可。

2- 模塊文件

Laravel 在 routes 文件夾中自帶了一些文件。由于我們已經(jīng)不在 RouteServiceProvider 中映射這些路由,所以可以直接刪除它們。接下來,我們創(chuàng)建一個(gè) modules.php 路由文件。

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

3- Books 模塊

在 app 文件夾中,創(chuàng)建 Modules/Books/routes.php 文件。在此文件中,我們可以定義該應(yīng)用 Books 模塊的路由規(guī)則。

<?php
use App\Modules\Books\ListBooks;
use Illuminate\Support\Facades\Route;
Route::get('/books', ListBooks::class);

你可以使用基于控制器 —— 也就是 Laravel 中默認(rèn)標(biāo)準(zhǔn)的路由方式,但我個(gè)人更喜歡 Good bye controllers, hello Request Handlers(放棄控制器,采用請(qǐng)求處理器) 的方式。 如下是 ListBooks 的實(shí)現(xiàn)。

<?php
namespace App\Modules\Books;
use App\Eloquent\Book;
use App\Modules\Books\Resources\BookResource;
class ListBooks
{
    public function __invoke(Book $book)
    {
        return BookResource::collection($book->paginate());
    }
}

以上代碼中 BookResource 是 Laravel 的資源轉(zhuǎn)換層。按照官方對(duì)于命名空間的建議,我們可以在 app/Modules/Books/Resources 文件夾中創(chuàng)建它。

<?php
namespace App\Modules\Books\Resources;
use Illuminate\Http\Resources\Json\Resource;
class BookResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->resource->id,
            'title' => $this->resource->title,
        ];
    }
}

4- Authors 模塊

我們還可以通過 Routes 文件來啟動(dòng) Authors 模塊。

<?php
use App\Modules\Authors\ListAuthors;
use Illuminate\Support\Facades\Route;
Route::get('/authors', ListAuthors::class);

注意:  app/Modules/Authors 這個(gè)命名空間正表示我們所編寫的文件,對(duì)于請(qǐng)求處理程序來說也是非常簡(jiǎn)單的。

<?php
namespace App\Modules\Authors;
use App\Eloquent\Author;
use App\Modules\Authors\Resources\AuthorResource;
class ListAuthors
{
    public function __invoke(Author $author)
    {
        return AuthorResource::collection($author->paginate());
    }
}

最后,我們將編寫的 Resource 類轉(zhuǎn)變?yōu)轫憫?yīng)式的 JSON 格式。

<?php
namespace App\Modules\Authors\Resources;
use App\Modules\Books\Resources\BookResource;
use Illuminate\Http\Resources\Json\Resource;
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);
            })
        ];
    }
}

注意資源是如何進(jìn)入另一個(gè)模塊以重用 BookResource 。 這通常不是一個(gè)比較好的選擇,因?yàn)槟K應(yīng)該是完全自給自足的,并且只能重用標(biāo)準(zhǔn)類,例如 Eloquent Models 或設(shè)計(jì)用于在任何模塊上通用的通用的組件。 這個(gè)問題的解決方案通常是將 BookResource 復(fù)制到 Authors 模塊中,從而可以在不使用另一個(gè)模塊的情況下進(jìn)行更改,反之亦然。 我決定保留這個(gè)跨模塊的用法,這個(gè)例子表現(xiàn)出一個(gè)很好的經(jīng)驗(yàn)方法,就是讓模塊之間彼此隔離,但是如果你認(rèn)為上面的例子很簡(jiǎn)單并且不太可能帶來任何問題。 始終確保編寫測(cè)試以涵蓋您編寫的功能,以避免其他人在不知不覺中修改您的應(yīng)用程序。

5- 結(jié)語(yǔ)

雖然這是一個(gè)非常簡(jiǎn)單的例子,但我希望它能夠讓人們根據(jù)自己的需要來輕松操作使用 Laravel 框架的結(jié)構(gòu)標(biāo)準(zhǔn)。您可以非常輕松地更改文件的位置,以便構(gòu)建基于模塊化的應(yīng)用程序。我的大多數(shù)項(xiàng)目都附帶了 App / Components 模塊,可以適用于任何模塊可重用的泛類型的基礎(chǔ)類; App / Eloquent ,Modules 文件夾可以用于保存 Eloquent 模型和數(shù)據(jù)庫(kù)關(guān)系模型,我們可以在其中構(gòu)建任何基于模塊化的功能。 這是我最近開始研究的應(yīng)用程序的文件夾目錄結(jié)構(gòu):

Laravel基于Module實(shí)現(xiàn)API架構(gòu)的示例

我希望每個(gè)人都能從中得到這個(gè)概念,每個(gè)模塊都有自己的需求,并且可以擁有自己的文件夾 / 實(shí)體 / 類 / 方法 / 屬性。沒有必要將所有模塊標(biāo)準(zhǔn)化完全相同,因?yàn)槟承┠K比其他模塊簡(jiǎn)單得多,并且不需要大量的結(jié)構(gòu)設(shè)計(jì)。此示例顯示 AccountChurn 模塊通過 HTTP 文件夾提供 API,同時(shí)仍通過控制臺(tái)提供 Artisan 命令。另一方面,AccountOverview 則僅提供 HTTP API,并且依賴倉(cāng)庫(kù)、值對(duì)象(bags)以及服務(wù)類(paginators)來提供更大的數(shù)據(jù)價(jià)值。

感謝各位的閱讀!關(guān)于“Laravel基于Module實(shí)現(xiàn)API架構(gòu)的示例”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI