利用 Laravel Resources 来整合第三方 API 数据

file

对于某些应用程序,可能需要第三方服务或者 API 来提取某些数据,将该数据转换为所需的响应,并将其传送到客户端界面。

为此,我们需要找到一种方法,方便从控制器发送到视图或最终用户界面的数据保持一致性。

因此,可能需要构建一个代表应用程序中所需资源的新对象或类。

您或许可能会想『为什么我需要它?』,因为,您不希望在应用程序中公开所有的 API 响应数据,此外,你可能需要转换该响应的某些字段等。

在本文中,我将向您展示一种简单的方法,将来自第三方 API 传入的数据转换为应用程序中的资源,以帮您保持一致性。

在进一步讨论之前:在这篇文章中,我假设您至少已经基本了解了什么是 API 以及该如何使用 API ,如何使用 Laravel 框架及其某些组件作为 Eloquent ORM 。 如果你不知道上面的文章大概在说明写什么,你可能会发现一些挑战性的概念,但是,嘿,不要气馁,我相信你会发现这篇文章会给你带来一定的价值。

一些关于 "Laravel resources" 的消息

'API Resources' 在 Laravel 5.5 中引入,作为是“将您的模型和模型集合表达并轻松转换为 JSON 数据格式”的一种方式。

虽然这是官方的说明,并且您发现此部分在官方网站的 Eloquent 文档上没有此目录索引,但您必须知道这些资源并未严格附加到 Eloquent ORM 当中。

在最基本的意义上来说,Eloquent 允许您将给指定对象转换为不同的对象。

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class UserResource extends Resource
{
    /**
     * 将资源转换为数组。
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

您可以通过阅读官方文档了解有关 Resources 的所有信息:Eloquent: API Resources

使用第三方 API

在使用第三方 API 时,您需要找到一种方法将传入的响应数据转换为结构一致的数据。

有关 Laravel 的最新消息:不久前 Eric L. Barnes 发表了一篇文章,描述了他如何使用 Laravel 为 laravel-news 网站建立一个前端页面,然后用 WordPress 作为后端并从 WordPress API 读取数据。你可以点击这里查看所有文章。 https://laravel-news.com/wordpress-api-with-laravel

因此,以具体案例为例。 假设您的应用程序中有一个 WordPress 存储库,它从 WordPress API 中提取数据。

<?php
class WordpressRepository {
    pubic function getPost($id)
    {
        $response = $this->apiClient->get(
            'post',
             $query = ['id' => $id]
        );
        // return as array
        return json_decode($response, true);
    }
}

假设您从 WordPress API 接收此对象(数据)

// wordpress version 0.1
{
    ID: 123
    post_title: "some title"
    post_content: "some content",
    post_author: "joe",
    publish_date: "01-01-2001"
}

您可以将此响应包装到一个数组中,然后在所有控制器或视图上使用此数据。

响应格式一致性

不妨想一想,如果 WordPress 的 API 更新了怎么办。假如新版本会返回一个不同格式的数据。

// wordpress version 0.1
{
    post_id: 123
    title: "some title"
    content: "some content",
    author: "joe",
    date: "01-01-2001"
}

那么你就需要在项目的多个位置把 $post['post_title'] 替换成 $post['title']

使用中间件来处理响应数据可以确保数据库的一致性。当响应的格式增加时,你只需要更新某段代码即可。

使用 API 资源批量处理数据

正如我之前提到的,你可以使用没有Eloquent的 「Resources」,下面就是一个很好的例子。
您需要做的第一件事是创建一个新的「Post」资源; 使用 artisan:

$ php artisan make:resource Post

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

返回单个资源实例

现在可以参照相同的例子,在你的 API 容器类中,你可以创建一个此资源新的实例,然后使用 resolve() 方法来返回转换后的对象(这将返回一个数组)。

<?php
class WordpressRepository {
    pubic function getPost($id)
    {
        $response = $this->apiClient->get(
            'post',
            $query = ['id' => $id]
        );
        $data = json_decode($response, true);
        return Post::make($data)->resolve();
    }
}

返回数据集合

我们可以创建一个专用的资源类 「PostCollection」。

$ php artisan make:resource PostCollection

<?php
namespace App\PublisherPlus\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PostCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return [
            'data' => $this->collection
                          ->map
                          ->toArray($request)
                          ->all(),
            'links' => [
               'self' => 'link-value',
             ],
        ];
    }
}

在上面的例子中,data 将会包含一个 Posts 数组,该数组的结构跟你在 Post 资源中定义的一样。

你可以在这里了解更多关于 「resource collections」 的信息。

API 资源

总结!

因此,如果你仔细研究 「resources」 的定义。你可以将其视为中间件,用于将已有数据转为新的、不同格式的对象或数组。

更多翻译文章请见 PHP / Laravel 开发者社区 https://laravel-china.org/topics/22537

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容

  • Laravel 学习交流 QQ 群:375462817 本文档前言Laravel 文档写的很好,只是新手看起来会有...
    Leonzai阅读 7,880评论 2 12
  • Laravel框架一:原理机制篇 Laravel作为在国内国外都颇为流行的PHP框架,风格优雅,其拥有自己的一些特...
    Mr_Z_Heng阅读 3,678评论 0 13
  • 必备品文档:DocumentationAPI: API Reference视频:Laracasts速查表:Lara...
    daos阅读 1,150评论 0 4
  • 必备品文档:DocumentationAPI: API Reference视频:Laracasts速查表:Lara...
    ethanzhang阅读 5,739评论 0 68
  • 去年有段时间得空,就把谷歌GAE的API权威指南看了一遍,收获颇丰,特别是在自己几乎独立开发了公司的云数据中心之后...
    骑单车的勋爵阅读 20,501评论 0 41