daltonmccleery / remote-models
有时您想使用 Eloquent,但数据存储在另一个应用程序的不同数据库中。
Requires
- php: ^8.1
- ext-pdo_sqlite: *
- ext-sqlite3: *
- guzzlehttp/guzzle: ^7.8
- illuminate/database: ^10.0 || ^11.0
- illuminate/support: ^10.0 || ^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.1
- orchestra/testbench: ^8.0 || ^9.0
- pestphp/pest: ^2.30
- pestphp/pest-plugin-faker: ^2.0
- pestphp/pest-plugin-laravel: ^2.2
README
有时您想使用 Eloquent,但数据存储在另一个应用程序的不同数据库中。
此包可用于“主机”应用程序和“远程”应用程序。以下详细说明了这两种用法,或者您可以查看这些示例。
要求
必须安装系统中的pdo-sqlite
PHP 扩展才能使用此包。
您需要在存储数据的宿主应用程序中设置任何端点。
安装
composer require daltonmccleery/remote-models
发布配置
建议发布配置文件;这将允许您添加主机域名、API 路径和任何模型。
php artisan vendor:publish --provider="RemoteModels\RemoteModelsServiceProvider" --force
远程使用
使用此包包括两个步骤
- 将
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 包的极大启发。
即将推出的功能
- 添加预缓存所有远程模型的命令以供部署。
- 添加本地数据库回退。