溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Laravel中如何用Saloon進行API集成

發(fā)布時間:2022-10-28 09:04:02 來源:億速云 閱讀:132 作者:iii 欄目:編程語言

今天小編給大家分享一下Laravel中如何用Saloon進行API集成的相關知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

像所有偉大的事情一樣,它以laravel new 開始并從那里開始,所以讓我們開始吧。 現(xiàn)在在安裝 Laravel 時,你可以使用 laravel installercomposer ——這部分由你決定。 如果可以的話,我會推薦安裝程序,因為它提供了簡單的選項來做更多的事情,而不僅僅是創(chuàng)建一個項目。 創(chuàng)建一個新項目并在您選擇的代碼編輯器中打開它。 一旦我們在那里,我們就可以開始了。

我們要建造什么? 我很高回答這個提問! 我們將構建與 GitHub API 的集成,以獲取可用于 repo 的工作流列表。 現(xiàn)在,如果你像我一樣在命令行上花費大量時間,這可能會非常有用。 你正在開發(fā)一個應用程序,將更改推送到一個分支或創(chuàng)建一個 PR - 它通過一個可能正在運行許多其他事情之一的工作流。 了解此工作流程的狀態(tài)有時會對您接下來的工作產(chǎn)生巨大影響。 功能齊全嗎? 我們的工作流程運行是否存在問題? 我們的測試或靜態(tài)分析是否通過了? 所有這些你通常會等待并檢查 GitHub 上的 repo 以查看狀態(tài)。 此集成將允許您運行 artisan 命令,獲取 repo 的可用工作流列表,并允許你觸發(fā)新的工作流運行。

所以到現(xiàn)在為止,composer 應該已經(jīng)完成了它的工作并安裝了一個完美的起點,一個 Laravel 應用程序。 接下來我們需要安裝 Saloon - 但我們要確保安裝 laravel 版本,所以在終端中運行以下命令:

composer require sammyjo20/saloon-laravel

就像這樣,我們已經(jīng)離更容易的集成更近了一步。 如果你在此階段有任何問題,請確保檢查您正在使用的 Laravel 和 PHP 版本,因為 Saloon 至少需要 Laravel 8 和 PHP 8!

所以,現(xiàn)在我們已經(jīng)安裝了 Saloon,我們需要創(chuàng)建一個新類。 在 Saloons 術語中,這些是「連接器」,連接器所做的一切就是創(chuàng)建一種以對象為中心的方式來表達 - 此 API 通過此類連接。 有一個方便的 artisan 命令允許您創(chuàng)建這些,因此運行以下 artisan 命令來創(chuàng)建 GitHub 連接器:

php artisan saloon:connector GitHub GitHubConnector

該命令分為兩部分,第一個參數(shù)是你正在創(chuàng)建的集成,第二個參數(shù)是要創(chuàng)建的連接器的名稱。這意味著你可以為集成創(chuàng)建多個連接器 - 如果需要的話可以通過多種不同方式進行連接。

這將在 app/Http/Integrations/GitHub/GitHubConnector.php 下為你創(chuàng)建一個新類,讓我們看一下,了解發(fā)生了什么。

我們看到的第一件事是我們的連接器擴展了「SaloonConnector」,這將使我們能夠讓我們的連接器在沒有大量樣板代碼的情況下工作。然后我們繼承了一個名為「AcceptsJson」的特征。現(xiàn)在,如果我們查看 Saloon 文檔,我們知道這是一個插件。這基本上為我們的請求添加了一個標頭,告訴第 3 方 API 我們想要接受 JSON 響應。接下來我們看到的是我們有一個方法來定義我們的連接器的基本 URL - 所以讓我們添加我們的:

public function defineBaseUrl(): string
{
    return 'https://api.github.com';
}

又好又干凈,我們甚至可以更進一步,這樣我們就可以處理應用程序中較少的松散字符串 - 所以讓我們看看我們?nèi)绾巫龅竭@一點。 在您的 config/services.php 文件中添加新的服務記錄:

'github' => [
    'url' => env('GITHUB_API_URL', 'https://api.github.com'),
]

這將允許我們在不同的環(huán)境中覆蓋它 - 為我們提供更好和更可測試的解決方案。 在本地,我們甚至可以使用他們的 OpenAPI 規(guī)范模擬 GitHub API,并對其進行測試以確保其正常工作。 但是,本教程是關于 Saloon 的,所以我離題了……現(xiàn)在讓我們重構我們的基本 URL 方法以使用配置:

public function defineBaseUrl(): string
{
    return (string) config('services.github.url');
}

如你所見,我們現(xiàn)在從配置中獲取新添加的記錄 - 并將其轉(zhuǎn)換為字符串以確保類型安全 - config() 可能會返回多種不同類型的結果。如果可以的話,我們希望對此進行嚴格處理。

接下來我們有默認 header 和默認配置,無須擔心默認 header 的內(nèi)容,因為我們將在一段時間內(nèi)自行處理身份驗證。但配置部分是我們可以為集成定義 guzzle 選項的地方,因為 Saloon 在服務引擎下使用了 Guzzle?,F(xiàn)在讓我們設置超時并繼續(xù),我們需要花一些時間配置它:

public function defaultConfig(): array
{
    return [
        'timeout' => 30,
    ];
}

我們現(xiàn)在已經(jīng)按照我們的需要配置了我們的連接器,如果我們有需要添加的配置,可以稍后再添加。下一步是開始考慮我們要發(fā)送的請求。如果我們查看 GitHub Actions API 的 API 文檔,我們有很多選擇,我們將從列出特定存儲庫的工作流開始:/repos/{owner}/{repo}/actions/workflows。運行以下 artisan 命令創(chuàng)建一個新請求:

php artisan saloon:request GitHub ListRepositoryWorkflowsRequest

同樣,第一個參數(shù)是集成,第二個參數(shù)是我們要創(chuàng)建的請求的名稱。我們需要確保為我們正在創(chuàng)建的請求命名集成,以便它存在于正確的位置,然后我們需要給它一個名稱。我將我的命名為 ListRepositoryWorkflowsRequest,因為我喜歡描述性的命名方法 - 但是,你可以隨意調(diào)整以適應你喜歡的命名方式。這將創(chuàng)建一個新文件供我們查看:app/Http/Integrations/GitHub/Requests/ListRepositoryWorkflowsRequest.php - 現(xiàn)在讓我們看一下。

我們再次在這里擴展了一個庫類,這次是預期的 SaloonRequest。這里會包含一個連接器屬性和一個方法。如果需要,我們可以修改這個方法 - 但默認的 GET 是我們現(xiàn)在需要的。然后我們有一個定義端點的方法。重構你的請求類,使其類似于以下示例:

 class ListRepositoryWorkflowsRequest extends SaloonRequest
{
    protected ?string $connector = GitHubConnector::class;

    protected ?string $method = Saloon::GET;

    public function __construct(
        public string $owner,
        public string $repo,
    ) {}

    public function defineEndpoint(): string
    {
        return "/repos/{$this->owner}/{$this->repo}/actions/workflows";
    }
}

我們所做的是添加一個構造函數(shù),它接受 repo 和 owner 作為參數(shù),然后我們可以在端點定義方法中使用它們。我們還將連接器設置為我們之前創(chuàng)建的 GitHubConnector。所以我們有一個我們知道可以發(fā)送的請求,我們可以從集成中走一小步,轉(zhuǎn)而考慮控制臺命令。

如果你之前沒有在 Laravel 中創(chuàng)建過控制臺命令,請務必查看 文檔。運行以下 artisan 命令來為此集成創(chuàng)建第一個命令:

php artisan make:command GitHub/ListRepositoryWorkflows

這將創(chuàng)建以下文件:app/Console/Commands/GitHub/ListRespositoryWorkflows.php。我們現(xiàn)在可以開始使用命令來發(fā)送請求并獲取我們關心的數(shù)據(jù)。當談到控制臺命令時,我總是做的第一件事就是考慮簽名。我希望如何調(diào)用它?它需要能夠解釋它正在做什么,同時具備一定的辨識度。我將會用 github:workflows 作為簽名,因為這很好地解釋了我想做的事情。我們還可以向控制臺命令添加描述,以便在瀏覽可用命令時更好地解釋目的:「通過存儲庫名稱從 GitHub 獲取工作流列表」。

最后,我們到了命令的 handle 方法,這部分是我們實際需要做的事情。在我們的例子中,我們將發(fā)送一個請求,獲取一些數(shù)據(jù)并以某種方式顯示這些數(shù)據(jù)。然而,在我們能夠做到這一點之前,我們還沒有完成一件事。那就是身份驗證。

對于每一個 API 集成,身份驗證都是關鍵方面之一——我們需要 API 不僅知道我們是誰,而且知道我們實際上被允許發(fā)出這個請求。如果你轉(zhuǎn)到 你的 GitHub 設置 并點擊進入開發(fā)人員設置和個人訪問令牌,在此你可以生成自己的設置。我建議使用這種方法,而不是為此使用完整的 OAuth 應用程序。我們不需要 OAuth,我們只需要用戶能夠訪問他們需要的內(nèi)容。

獲得訪問令牌后,我們需要將其添加到我們的 .env 文件中,并確保我們可以通過配置提取它。

GITHUB_API_TOKEN=ghp_loads-of-letters-and-numbers-here

我們現(xiàn)在可以在 github 下的 config/services.php 中擴展我們的服務,添加這個令牌:

'github' => [
    'url' => env('GITHUB_API_URL', 'https://api.github.com'),
    'token' => env('GITHUB_API_TOKEN'),
]

現(xiàn)在我們有了一個加載這個令牌的好方法,我們可以回到我們的控制臺命令!我們需要修改我們的簽名以允許我們接受所有者和存儲庫作為參數(shù):

 class ListRepositoryWorkflows extends Command
{
    protected $signature = 'github:workflows
        {owner : The owner or organisation.}
        {repo : The repository we are looking at.}
    ';

    protected $description = 'Fetch a list of workflows from GitHub by the repository name.';

    public function handle(): int
    {
        return 0;
    }
}

現(xiàn)在我們可以將注意力轉(zhuǎn)移到 handle 方法上:

public function handle(): int
{
    $request = new ListRepositoryWorkflowsRequest(
        owner: $this->argument('owner'),
        repo: $this->argument('repo'),
    );

    return self::SUCCESS;
}

在這里,我們開始通過將參數(shù)直接傳遞到請求本身來構建我們的請求,但是我們可能想要做的是創(chuàng)建一些局部變量來提供一些控制臺反饋:

 public function handle(): int
{
    $owner = (string) $this->argument('owner');
    $repo = (string) $this->argument('repo');

    $request = new ListRepositoryWorkflowsRequest(
        owner: $owner,
        repo: $repo,
    );

    $this->info(
        string: "Fetching workflows for {$owner}/{$repo}",
    );

    return self::SUCCESS;
}

所以我們有一些反饋給用戶,這對于控制臺命令來說總是很重要的。現(xiàn)在我們需要添加我們的身份驗證令牌并實際發(fā)送請求:

 public function handle(): int
{
    $owner = (string) $this->argument('owner');
    $repo = (string) $this->argument('repo');

    $request = new ListRepositoryWorkflowsRequest(
        owner: $owner,
        repo: $repo,
    );

    $request->withTokenAuth(
        token: (string) config('services.github.token'),
    );

    $this->info(
        string: "Fetching workflows for {$owner}/{$repo}",
    );

    $response = $request->send();

    return self::SUCCESS;
}

如果你修改上述內(nèi)容并在 $response->json() 上執(zhí)行 dd(),然后運行命令:

php artisan github:workflows laravel laravel

這將獲得 laravel/laravel repo 的工作流列表。我們的命令將允許你使用任何公共存儲庫,如果你希望它更具體,你可以建立一個要檢查的存儲庫選項列表,而不是接受參數(shù) —— 但這部分取決于你個人。對于本教程,我將重點關注更廣泛更開放的用例。

現(xiàn)在,我們從 GitHub API 得到的響應非常好且信息豐富,但它需要轉(zhuǎn)換才能顯示,如果我們孤立地查看它,則沒有上下文。相反,我們將在我們的請求中添加另一個插件,這將允許我們將響應轉(zhuǎn)換為 DTO(域傳輸對象),這是處理此問題的好方法。它將允許我們放松我們習慣于從 API 獲取的靈活數(shù)組,并獲得更具上下文感知的東西。讓我們?yōu)楣ぷ髁鲃?chuàng)建一個 DTO,創(chuàng)建一個新文件:app/Http/Integrations/GitHub/DataObjects/Workflow.php 并向其中添加以下代碼:

 class Workflow
{
    public function __construct(
        public int $id,
        public string $name,
        public string $state,
    ) {}

    public static function fromSaloon(array $workflow): static
    {
        return new static(
            id: intval(data_get($workflow, 'id')),
            name: strval(data_get($workflow, 'name')),
            state: strval(data_get($workflow, 'state')),
        );
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'state' => $this->state,
        ];
    }
}

我們有一個構造函數(shù),其中包含我們要顯示的工作流的重要部分,一個 fromSaloon 方法,它將一個數(shù)組從一個 saloon 轉(zhuǎn)換為一個新的 DTO,以及一個用于將 DTO 顯示回數(shù)組的數(shù)組方法當我們需要它時。在我們的ListRepositoryWorkflowsRequest 中,我們需要繼承一個新特征并添加一個新方法:

 class ListRepositoryWorkflowsRequest extends SaloonRequest
{
    use CastsToDto;

    protected ?string $connector = GitHubConnector::class;

    protected ?string $method = Saloon::GET;

    public function __construct(
        public string $owner,
        public string $repo,
    ) {}

    public function defineEndpoint(): string
    {
        return "/repos/{$this->owner}/{$this->repo}/actions/workflows";
    }

    protected function castToDto(SaloonResponse $response): Collection
    {
        return (new Collection(
            items: $response->json('workflows'),
        ))->map(function ($workflow): Workflow {
            return Workflow::fromSaloon(
                workflow: $workflow,
            );
        });
    }
}

我們繼承了 CastsToDto trait,它允許這個請求在響應中調(diào)用 dto 方法,然后我們添加一個 castToDto 方法,我們可以控制它的轉(zhuǎn)換方式。我們希望它返回一個新的集合,因為有多個工作流,使用響應正文的工作流部分。然后我們映射集合中的每個項目 - 并將其轉(zhuǎn)換為 DTO。現(xiàn)在我們既可以這樣做,也可以使用 DTO 構建集合:

protected function castToDto(SaloonResponse $response): Collection
{
    return new Collection(
        items: $response->collect('workflows')->map(fn ($workflow) =>
            Workflow::fromSaloon(
                workflow: $workflow
            ),
        )
    );
}

你可以在這里選擇最適合你的方式。我個人更喜歡第一種方法,因為我喜歡逐步了解邏輯,但是這兩種方法都沒有錯——選擇權在你?,F(xiàn)在回到命令,我們現(xiàn)在需要考慮我們希望如何顯示這些信息:

public function handle(): int
{
    $owner = (string) $this->argument('owner');
    $repo = (string) $this->argument('repo');

    $request = new ListRepositoryWorkflowsRequest(
        owner: $owner,
        repo: $repo,
    );

    $request->withTokenAuth(
        token: (string) config('services.github.token'),
    );

    $this->info(
        string: "Fetching workflows for {$owner}/{$repo}",
    );

    $response = $request->send();

    if ($response->failed()) {
        throw $response->toException();
    }

    $this->table(
        headers: ['ID', 'Name', 'State'],
        rows: $response
            ->dto()
            ->map(fn (Workflow $workflow) =>
                  $workflow->toArray()
            )->toArray(),
    );

    return self::SUCCESS;
}

因此,我們創(chuàng)建一個帶有標題的表,然后對于我們想要響應 DTO 的行,我們將映射返回的集合,將每個 DTO 轉(zhuǎn)換回要顯示的數(shù)組。從響應數(shù)組轉(zhuǎn)換為 DTO 再轉(zhuǎn)換回數(shù)組,這似乎違反直覺,但這會強制執(zhí)行類型,以便 ID、名稱和狀態(tài)在預期時始終存在,并且不會給出任何有趣的結果.它允許正常響應數(shù)組可能沒有它的一致性,如果我們愿意,我們可以將它轉(zhuǎn)換為一個值對象,我們可以在其中附加行為。如果我們現(xiàn)在運行我們的命令,我們現(xiàn)在應該會看到一個漂亮的表格輸出,它比幾行字符串更容易閱讀:

php artisan github:workflows laravel laravel
Fetching workflows for laravel/laravel
+----------+------------------+--------+
| ID       | Name             | State  |
+----------+------------------+--------+
| 12345678 | pull requests    | active |
| 87654321 | Tests            | active |
| 18273645 | update changelog | active |
+----------+------------------+--------+

最后,僅僅列出這些工作流程是很棒的——但讓我們以科學的名義更進一步。假設你正在針對你的一個存儲庫運行此命令,并且想手動運行更新更改日志?或者,也許你希望使用你的實時生產(chǎn)服務器或你可能想到的任何事件在 cron 上觸發(fā)它?我們可以將變更日志設置為每天午夜運行一次,這樣我們就可以在變更日志中獲得每日回顧或任何我們可能想要的內(nèi)容。讓我們創(chuàng)建另一個控制臺命令來創(chuàng)建一個新的工作流調(diào)度事件:

php artisan saloon:request GitHub CreateWorkflowDispatchEventRequest

在這個新文件 app/Http/Integrations/GitHub/Requests/CreateWorkflowDispatchEventRequest.php 中添加以下代碼,以便我們?yōu)g覽它:

class CreateWorkflowDispatchEventRequest extends SaloonRequest
{
    use HasJsonBody;

    protected ?string $connector = GitHubConnector::class;

    public function defaultData(): array
    {
        return [
            'ref' => 'main',
        ];
    }

    protected ?string $method = Saloon::POST;

    public function __construct(
        public string $owner,
        public string $repo,
        public string $workflow,
    ) {}

    public function defineEndpoint(): string
    {
        return "/repos/{$this->owner}/{$this->repo}/actions/workflows/{$this->workflow}/dispatches";
    }
}

通過設置連接器,并繼承 HasJsonBody 特征以允許我們發(fā)送數(shù)據(jù)。該方法已設置為 POST 請求,因為我們要發(fā)送數(shù)據(jù)。然后我們有一個構造函數(shù),它接受構建端點的 URL 部分。

最后,我們在 defaultData 中有圓頂默認數(shù)據(jù),我們可以使用它來設置此發(fā)布請求的默認值。與 repo 一樣,我們可以在此處傳遞提交哈?;蚍种Q - 所以我將默認設置為 main,因為這就是我通常所說的生產(chǎn)分支。

我們現(xiàn)在可以觸發(fā)這個端點來調(diào)度一個新的工作流事件,所以讓我們創(chuàng)建一個控制臺命令來控制它,這樣我們就可以從我們的 CLI 運行它:

php artisan make:command GitHub/CreateWorkflowDispatchEvent

現(xiàn)在讓我們編寫具體的邏輯,我們可以了解正在發(fā)生的事情:

class CreateWorkflowDispatchEvent extends Command
{
    protected $signature = 'github:dispatch
        {owner : The owner or organisation.}
        {repo : The repository we are looking at.}
        {workflow : The ID of the workflow we want to dispatch.}
        {branch? : Optional: The branch name to run the workflow against.}
    ';

    protected $description = 'Create a new workflow dispatch event for a repository.';

    public function handle(): int
    {
        $owner = (string) $this->argument('owner');
        $repo = (string) $this->argument('repo');
        $workflow = (string) $this->argument('workflow');

        $request = new CreateWorkflowDispatchEventRequest(
            owner: $owner,
            repo: $repo,
            workflow: $workflow,
        );

        $request->withTokenAuth(
            token: (string) config('services.github.token'),
        );

        if ($this->hasArgument('branch')) {
            $request->setData(
                data: ['ref' => $this->argument('branch')],
            );
        }

        $this->info(
            string: "Requesting a new workflow dispatch for {$owner}/{$repo} using workflow: {$workflow}",
        );

        $response = $request->send();

        if ($response->failed()) {
            throw $response->toException();
        }

        $this->info(
            string: 'Request was accepted by GitHub',
        );

        return self::SUCCESS;
    }
}

就像在我們有簽名和描述之前一樣,這次我們的簽名有一個可選的分支,以防我們想要覆蓋請求中的默認值。所以在我們的處理方法中,我們可以簡單地檢查輸入是否有參數(shù) branch,如果有,我們可以解析它并為請求設置數(shù)據(jù)。然后我們向 CLI 提供一些反饋,讓用戶知道我們在做什么 - 并發(fā)送請求。如果此時一切順利,我們可以簡單地輸出一條消息,通知用戶 GitHub 接受了請求。但是,如果出現(xiàn)問題,我們希望拋出特定的異常,至少在開發(fā)過程中是這樣。

最后一個請求的主要警告是,我們的工作流程設置為通過在工作流程中添加一個新的 on 項目來由 webhook 觸發(fā):

on: workflow_dispatch

以上就是“Laravel中如何用Saloon進行API集成”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

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

AI