daltonmccleery/remote-models

有时您想使用 Eloquent,但数据存储在另一个应用程序的不同数据库中。

1.2.6 2024-09-07 19:05 UTC

This package is auto-updated.

Last update: 2024-09-07 19:07:19 UTC


README

有时您想使用 Eloquent,但数据存储在另一个应用程序的不同数据库中。

此包可用于“主机”应用程序和“远程”应用程序。以下详细说明了这两种用法,或者您可以查看这些示例

要求

必须安装系统中的pdo-sqlite PHP 扩展才能使用此包。

您需要在存储数据的宿主应用程序中设置任何端点。

安装

composer require daltonmccleery/remote-models

发布配置

建议发布配置文件;这将允许您添加主机域名、API 路径和任何模型。

php artisan vendor:publish --provider="RemoteModels\RemoteModelsServiceProvider" --force

远程使用

使用此包包括两个步骤

  1. RemoteModel 特性添加到模型中。

就这么多。

class Celebrity extends Model
{
    use \RemoteModels\RemoteModel;
}

现在,您可以在任何地方使用此模型,并且它将表现得好像该表存在于您的应用程序中。

$celebrity = Celebrity::where('name', 'Dwayne Johnson')->first();

这将允许您添加主机域名、API 路径和任何模型。

自定义端点

您可以提供一个自定义端点给远程模型,当模型被加载时将被调用。如果您这样做并且在该宿主应用程序上安装了此包,您将需要创建自己的 API 端点。

class Celebrity extends Model
{
    use \RemoteModels\RemoteModel;

    protected $remoteEndpoint = '/v1/celebrities';
}

自定义模式

远程模型将自动从第一个 API 调用中发现模式,但是如果您想对模式或本地保存的字段有更多控制,您可以添加到具有列类型转换的 $schema 属性中。

class Celebrity extends Model
{
    use \RemoteModels\RemoteModel;

    protected $remoteSchema = [
        'name' => 'string',
        'birthday' => 'datetime' 
    ];
}

主机使用

此包依赖于一个单独的 Laravel 应用程序,该应用程序作为“主机”存储模型及其数据。您需要要么在宿主应用程序上安装此包并将您希望向“远程”应用程序公开的“远程”模型输入。

// config/remote-models.php
'host-models' => [
    \App\Models\Celebrity::class
]

自定义端点

如果您在远程应用程序上使用自定义端点,您需要设置该自定义路由。以下是一个示例

Route::post(
    config('remote-models.api-path') . '/v1/celebrities',
    fn (\RemoteModels\Http\Requests\CustomRemoteModelRequest $request) => $request->returnRemoteModels(Celebrity::class)
);

如果您没有在“主机”应用程序上安装此包,则需要为每个计划使用的远程模型设置自定义端点。您还需要手动验证提供的 API 密钥。以下是一个示例

Route::post('/api/_remote/_models/v1/celebrities', fn () => response()->json(Celebrity::paginate())));

您不需要在“主机”应用程序上安装此包。如果您不这样做,您将需要为希望使用的模型设置自己的 API 端点。建议使用 Laravel 的默认 分页

缓存间隔

您可以使用 cache-ttl 配置选项设置远程数据的缓存时间。以下是一些示例值

// config/remote-models.php
'cache-ttl' => '1m | 1w | 1d | 1h' // 1 month | 1 week | 1 day | 1 hour

外部主机数据

可能存在您无法控制“主机”应用程序的情况,例如,它可能是 Google 表格或第三方 API,但您仍然希望有一种方式可以使用 Eloquent 查询这些数据。

您的模型需要实现 RemoteModelInterface 接口,并包含基础 RemoteModelManagement 特性。这将使您实现设置自定义模式(可选)和递归获取数据的2个方法。在这个例子中,$remoteEndpoint 是可选的。

您可以通过以下示例创建自己的远程模型:

class Celebrity extends Model implements \RemoteModels\Interfaces\RemoteModelInterface
{
    use \RemoteModels\RemoteModelManagement;

    public function migrate(): void
    {
        $this->createRemoteModelTable(schemaCallback: function (array $schema) {
        
            // Make any modifications to the column schema before the sqlite table is created.

            return $schema;
        });

        $this->loadRemoteModelData();
    }
    
    public function loadRemoteModelData(int $page = 1): void
    {
        // Normal operation is a POST request with the config API key,
        // but you are free to modify the API call as you like.
        $response = \Illuminate\Support\Facades\Http::get($this->getRemoteModelEndpoint());
        
        $data = $response->json();

        // `insertRemoteModelData` is available and takes an array of data to be inserted.
        $this->insertRemoteModelData($data['data'], $data['per_page'] ?? 15);

        // Call the next page, if available.
        if ((int) $data['current_page'] < (int) $data['last_page']) {
            $this->loadRemoteModelData((int) $data['current_page'] + 1);
        }
    }
}

工作原理

当调用模型时,它将使用模型的名称对自定义端点或预定义端点进行API调用。这个预定义的API端点可以在配置文件中进行配置。

在内部,这个包只为该模型及其所有数据创建和缓存一个SQLite数据库。它创建一个表,并用返回的、分页的API数据填充它。如果由于某种原因无法缓存.sqlite文件,它将默认使用内存中的sqlite数据库。

这个包受到了Caleb Porzio的 Sushi 包的极大启发。

即将推出的功能

  • 添加预缓存所有远程模型的命令以供部署。
  • 添加本地数据库回退。