Skip to content

Commit 8006217

Browse files
committed
Add QueryBuilder for models
1 parent d986d8c commit 8006217

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## Unreleased
9+
### Added
10+
- Query builder with `where()->get()` support for remote models.
911

1012
## [0.4.1] - 2025-07-10
1113
### Added

src/Models/Model.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ protected static function client(): ApiGatewayClientInterface
3939
return app(ApiGatewayClientInterface::class);
4040
}
4141

42+
/**
43+
* Start a new query for the model.
44+
*/
45+
public static function query(): QueryBuilder
46+
{
47+
return new QueryBuilder(static::class);
48+
}
49+
50+
/**
51+
* Filter models by the given column and value.
52+
*/
53+
public static function where(string $column, mixed $value): QueryBuilder
54+
{
55+
return static::query()->where($column, $value);
56+
}
57+
4258
/**
4359
* Get all models.
4460
*/

src/Models/QueryBuilder.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Kroderdev\LaravelMicroserviceCore\Models;
4+
5+
use Illuminate\Support\Collection;
6+
7+
class QueryBuilder
8+
{
9+
protected string $model;
10+
11+
protected array $filters = [];
12+
13+
public function __construct(string $model)
14+
{
15+
$this->model = $model;
16+
}
17+
18+
public function where(string $column, mixed $value): static
19+
{
20+
$this->filters[$column] = $value;
21+
22+
return $this;
23+
}
24+
25+
public function get($columns = ['*']): Collection
26+
{
27+
$model = $this->model;
28+
29+
$response = $model::client()->get($model::endpoint(), $this->filters);
30+
$data = $this->parseResponse($response);
31+
32+
return $model::fromCollection($data['data'] ?? $data);
33+
}
34+
35+
protected function parseResponse($response): array
36+
{
37+
if ($response === null) {
38+
return [];
39+
}
40+
41+
if (is_array($response)) {
42+
return $response;
43+
}
44+
45+
if ($response instanceof Collection) {
46+
return $response->toArray();
47+
}
48+
49+
if (method_exists($response, 'json')) {
50+
return $response->json();
51+
}
52+
53+
return (array) $response;
54+
}
55+
}

tests/Models/ApiModelTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,29 @@ public function delete_users_gateway()
209209
], $this->gateway->getCalls());
210210
}
211211

212+
/** @test */
213+
public function where_get_filters_results()
214+
{
215+
$this->gateway = new class () extends FakeGatewayClient {
216+
public function get(string $uri, array $query = [])
217+
{
218+
parent::get($uri, $query);
219+
220+
return ['data' => [
221+
['id' => 7, 'name' => $query['name'] ?? ''],
222+
]];
223+
}
224+
};
225+
$this->app->bind(ApiGatewayClientInterface::class, fn () => $this->gateway);
226+
227+
$users = RemoteUser::where('name', 'Alice')->get();
228+
229+
$this->assertSame([
230+
['method' => 'GET', 'uri' => '/users', 'query' => ['name' => 'Alice']],
231+
], $this->gateway->getCalls());
232+
$this->assertCount(1, $users);
233+
$this->assertEquals('Alice', $users[0]->name);
234+
}
212235

213236
/** @test */
214237
public function from_api_response_maps_nested_relations()

0 commit comments

Comments
 (0)