Skip to content

Commit 1efbdef

Browse files
josip-miloticJosip MilotićStyleCIBot
authored
Remote resolve improvements #minor (#80)
* Added additional properties to remote custom field type, added aditional endpoint for remote cf resolution * Apply fixes from StyleCI * Added response caching * Apply fixes from StyleCI Co-authored-by: Josip Milotić <[email protected]> Co-authored-by: StyleCI Bot <[email protected]>
1 parent 91d58d8 commit 1efbdef

File tree

5 files changed

+94
-10
lines changed

5 files changed

+94
-10
lines changed

config/asseco-custom-fields.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,14 @@
9090
'prefix' => 'api',
9191
'middleware' => ['api'],
9292
],
93+
94+
/**
95+
* Determines if the response from resolving a remote custom field should be cached.
96+
*/
97+
'should_cache_remote' => false,
98+
99+
/**
100+
* Number of seconds that the remote custom field response should remain in cache.
101+
*/
102+
'remote_cache_ttl' => 3600,
93103
];
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('custom_field_remote_types', function (Blueprint $table) {
17+
$table->string('data_path')->nullable()->after('mappings');
18+
$table->string('identifier_property')->nullable()->after('mappings');
19+
});
20+
}
21+
22+
/**
23+
* Reverse the migrations.
24+
*
25+
* @return void
26+
*/
27+
public function down()
28+
{
29+
Schema::table('custom_field_remote_types', function (Blueprint $table) {
30+
$table->dropColumn('data_path');
31+
});
32+
33+
Schema::table('custom_field_remote_types', function (Blueprint $table) {
34+
$table->dropColumn('identifier_property');
35+
});
36+
}
37+
};

routes/api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
Route::apiResource('remote', RemoteCustomFieldController::class)->only(['index', 'store']);
4747
Route::match(['put', 'patch'], 'remote/{remote_type}', [RemoteCustomFieldController::class, 'update'])->name('remote.update');
4848
Route::get('remote/{remote_type}/resolve', [RemoteCustomFieldController::class, 'resolve'])->name('remote.resolve');
49+
Route::get('remote/{remote_type}/resolve/{identifier_value}', [RemoteCustomFieldController::class, 'resolveByIdentifierValue'])->name('remote.resolveByIdentifierValue');
4950

5051
Route::get('selection', [SelectionCustomFieldController::class, 'index'])->name('selection.index');
5152
Route::post('selection/{plain_type}', [SelectionCustomFieldController::class, 'store'])->name('selection.store');

src/App/Http/Controllers/RemoteCustomFieldController.php

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
use Asseco\CustomFields\App\Http\Requests\RemoteCustomFieldRequest;
1111
use Asseco\CustomFields\App\Http\Requests\RemoteTypeRequest;
1212
use Asseco\CustomFields\App\Traits\TransformsOutput;
13-
use Illuminate\Http\Client\Response;
1413
use Illuminate\Http\JsonResponse;
1514
use Illuminate\Support\Arr;
1615
use Illuminate\Support\Facades\DB;
17-
use Illuminate\Support\Facades\Http;
1816

1917
/**
2018
* @group Remote Custom Fields
@@ -104,14 +102,31 @@ public function update(RemoteTypeRequest $request, RemoteType $remoteType): Json
104102
*/
105103
public function resolve(RemoteType $remoteType): JsonResponse
106104
{
107-
/**
108-
* @var Response $response
109-
*/
110-
$response = Http::withHeaders($remoteType->headers ?: [])
111-
->withBody($remoteType->body, 'application/json')
112-
->{$remoteType->method}($remoteType->url);
113-
114-
$transformed = $this->transform($response->json(), json_decode($remoteType->mappings, true));
105+
$data = $remoteType->getRemoteData();
106+
107+
$data = $remoteType->data_path ? Arr::get($data, $remoteType->data_path) : $data;
108+
109+
$transformed = $this->transform($data, json_decode($remoteType->mappings, true));
110+
111+
return response()->json($transformed);
112+
}
113+
114+
/**
115+
* Display the specified resource.
116+
*
117+
* @param RemoteType $remoteType
118+
* @param string $identifierValue
119+
* @return JsonResponse
120+
*/
121+
public function resolveByIdentifierValue(RemoteType $remoteType, string $identifierValue): JsonResponse
122+
{
123+
$data = $remoteType->getRemoteData();
124+
125+
$data = $remoteType->data_path ? Arr::get($data, $remoteType->data_path) : $data;
126+
127+
$data = collect($data)->where($remoteType->identifier_property, $identifierValue)->first();
128+
129+
$transformed = $this->mapSingle($remoteType->mappings, $data);
115130

116131
return response()->json($transformed);
117132
}

src/App/Models/RemoteType.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
88
use Asseco\CustomFields\Database\Factories\RemoteTypeFactory;
99
use Illuminate\Database\Eloquent\Factories\HasFactory;
1010
use Illuminate\Database\Eloquent\Relations\MorphMany;
11+
use Illuminate\Support\Facades\Cache;
12+
use Illuminate\Support\Facades\Http;
1113

1214
class RemoteType extends ParentType implements \Asseco\CustomFields\App\Contracts\RemoteType
1315
{
1416
use HasFactory;
1517

18+
protected const CACHE_PREFIX = 'remote_custom_field_';
19+
1620
protected $table = 'custom_field_remote_types';
1721

1822
protected $guarded = ['id', 'created_at', 'updated_at'];
@@ -39,4 +43,21 @@ public function getNameAttribute()
3943
{
4044
return 'remote';
4145
}
46+
47+
public function getRemoteData()
48+
{
49+
$cacheKey = 'remote_custom_field_' . $this->id;
50+
51+
if (config('asseco-custom-fields.should_cache_remote') && Cache::has($cacheKey)) {
52+
return Cache::get($cacheKey);
53+
}
54+
55+
$response = Http::withHeaders($this->headers ?: [])
56+
->withBody($this->body, 'application/json')
57+
->{$this->method}($this->url)->json();
58+
59+
Cache::put($cacheKey, $response, config('asseco-custom-fields.remote_cache_ttl'));
60+
61+
return $response;
62+
}
4263
}

0 commit comments

Comments
 (0)