Skip to content

Commit 9ea7968

Browse files
authored
Merge pull request #46 from Lomkit/feature/caches-common-operations
Feature/caches common operations
2 parents f0ae4c2 + 0de0dc8 commit 9ea7968

20 files changed

+362
-278
lines changed

config/rest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@
2626
],
2727
],
2828

29+
/*
30+
|--------------------------------------------------------------------------
31+
| Rest Resources
32+
|--------------------------------------------------------------------------
33+
|
34+
| This is the core of the Laravel Rest Api package, resources allows you
35+
| to define your own logic and take full advantage of your API. Here
36+
| you can disable the cache on all exposed data
37+
|
38+
*/
39+
40+
'resources' => [
41+
'cache' => [
42+
'enabled' => true,
43+
'default' => 5, // Cache minutes by default
44+
],
45+
],
46+
2947
/*
3048
|--------------------------------------------------------------------------
3149
| Rest Authorizations
@@ -38,6 +56,10 @@
3856

3957
'authorizations' => [
4058
'enabled' => true,
59+
'cache' => [
60+
'enabled' => true,
61+
'default' => 5, // Cache minutes by default
62+
],
4163
],
4264

4365
/*

src/Actions/Actionable.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Lomkit\Rest\Actions;
44

5+
use Illuminate\Support\Facades\Cache;
56
use Lomkit\Rest\Http\Requests\RestRequest;
67

78
trait Actionable
@@ -18,6 +19,30 @@ public function actions(RestRequest $request): array
1819
return [];
1920
}
2021

22+
/**
23+
* Get the resource's actions.
24+
*
25+
* @param \Lomkit\Rest\Http\Requests\RestRequest $request
26+
*
27+
* @return array
28+
*/
29+
public function getActions(\Lomkit\Rest\Http\Requests\RestRequest $request): array
30+
{
31+
$resolver = function () use ($request) {
32+
return $this->actions($request);
33+
};
34+
35+
if ($this->isResourceCacheEnabled()) {
36+
return Cache::remember(
37+
$this->getResourceCacheKey($request, 'actions'),
38+
$this->cacheResourceFor(),
39+
$resolver
40+
);
41+
}
42+
43+
return $resolver();
44+
}
45+
2146
/**
2247
* Check if a specific action exists.
2348
*
@@ -28,7 +53,7 @@ public function actions(RestRequest $request): array
2853
*/
2954
public function actionExists(RestRequest $request, string $actionKey): bool
3055
{
31-
return collect($this->actions($request))
56+
return collect($this->getActions($request))
3257
->contains(function (Action $action) use ($actionKey) {
3358
return $action->uriKey() === $actionKey;
3459
});
@@ -44,7 +69,7 @@ public function actionExists(RestRequest $request, string $actionKey): bool
4469
*/
4570
public function action(RestRequest $request, string $actionKey): Action
4671
{
47-
return collect($this->actions($request))
72+
return collect($this->getActions($request))
4873
->sole(function (Action $action) use ($actionKey) {
4974
return $action->uriKey() === $actionKey;
5075
})

src/Concerns/Authorizable.php

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
namespace Lomkit\Rest\Concerns;
44

5+
use Illuminate\Auth\Access\Response;
6+
use Illuminate\Support\Facades\Cache;
57
use Illuminate\Support\Facades\Gate;
8+
use Illuminate\Support\Str;
9+
use Lomkit\Rest\Http\Requests\RestRequest;
10+
use Lomkit\Rest\Tests\Support\Models\Model;
611

712
trait Authorizable
813
{
@@ -19,7 +24,31 @@ trait Authorizable
1924
public function authorizeTo($ability, $model)
2025
{
2126
if ($this->isAuthorizingEnabled()) {
22-
Gate::authorize($ability, $model);
27+
$resolver = function () use ($ability, $model) {
28+
return Gate::authorize($ability, $model);
29+
};
30+
31+
if ($this->isAuthorizationCacheEnabled()) {
32+
$gatePasses = Cache::remember(
33+
$this->getAuthorizationCacheKey(
34+
app(RestRequest::class),
35+
sprintf(
36+
'%s.%s.%s',
37+
$ability,
38+
$model instanceof Model ? Str::snake((new \ReflectionClass($model))->getShortName()) : $model,
39+
$model instanceof Model ? $model->getKey() : null,
40+
)
41+
),
42+
$this->cacheAuthorizationFor(),
43+
$resolver
44+
);
45+
} else {
46+
$gatePasses = $resolver();
47+
}
48+
49+
if (!$gatePasses) {
50+
Response::deny()->authorize();
51+
}
2352
}
2453
}
2554

@@ -34,7 +63,27 @@ public function authorizeTo($ability, $model)
3463
public function authorizedTo($ability, $model)
3564
{
3665
if ($this->isAuthorizingEnabled()) {
37-
return Gate::check($ability, $model);
66+
$resolver = function () use ($ability, $model) {
67+
return Gate::check($ability, $model);
68+
};
69+
70+
if ($this->isAuthorizationCacheEnabled()) {
71+
return Cache::remember(
72+
$this->getAuthorizationCacheKey(
73+
app(RestRequest::class),
74+
sprintf(
75+
'%s.%s.%s',
76+
$ability,
77+
$model instanceof Model ? Str::snake((new \ReflectionClass($model))->getShortName()) : $model,
78+
$model instanceof Model ? $model->getKey() : null,
79+
)
80+
),
81+
$this->cacheAuthorizationFor(),
82+
$resolver
83+
);
84+
}
85+
86+
return $resolver();
3887
}
3988

4089
return true;

src/Concerns/Resource/ConfiguresRestParameters.php

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
namespace Lomkit\Rest\Concerns\Resource;
44

5+
use Illuminate\Support\Facades\Cache;
56
use Lomkit\Rest\Http\Requests\RestRequest;
67

78
trait ConfiguresRestParameters
89
{
10+
//@TODO: V2: Pass all fields / relations / other methods in private
911
/**
1012
* The fields that could be provided.
1113
*
@@ -18,6 +20,30 @@ public function fields(RestRequest $request): array
1820
return [];
1921
}
2022

23+
/**
24+
* Get the resource's fields.
25+
*
26+
* @param \Lomkit\Rest\Http\Requests\RestRequest $request
27+
*
28+
* @return array
29+
*/
30+
public function getFields(\Lomkit\Rest\Http\Requests\RestRequest $request): array
31+
{
32+
$resolver = function () use ($request) {
33+
return $this->fields($request);
34+
};
35+
36+
if ($this->isResourceCacheEnabled()) {
37+
return Cache::remember(
38+
$this->getResourceCacheKey($request, 'fields'),
39+
$this->cacheResourceFor(),
40+
$resolver
41+
);
42+
}
43+
44+
return $resolver();
45+
}
46+
2147
/**
2248
* Get nested fields by prefixing them with a given prefix.
2349
*
@@ -37,7 +63,7 @@ public function getNestedFields(RestRequest $request, string $prefix = '', array
3763
function ($field) use ($prefix) {
3864
return $prefix.$field;
3965
},
40-
$this->fields($request)
66+
$this->getFields($request)
4167
);
4268

4369
foreach (
@@ -72,6 +98,30 @@ public function scopes(RestRequest $request): array
7298
return [];
7399
}
74100

101+
/**
102+
* Get the resource's scopes.
103+
*
104+
* @param \Lomkit\Rest\Http\Requests\RestRequest $request
105+
*
106+
* @return array
107+
*/
108+
public function getScopes(\Lomkit\Rest\Http\Requests\RestRequest $request): array
109+
{
110+
$resolver = function () use ($request) {
111+
return $this->scopes($request);
112+
};
113+
114+
if ($this->isResourceCacheEnabled()) {
115+
return Cache::remember(
116+
$this->getResourceCacheKey($request, 'scopes'),
117+
$this->cacheResourceFor(),
118+
$resolver
119+
);
120+
}
121+
122+
return $resolver();
123+
}
124+
75125
/**
76126
* The limits that could be provided.
77127
*
@@ -87,4 +137,28 @@ public function limits(RestRequest $request): array
87137
50,
88138
];
89139
}
140+
141+
/**
142+
* Get the resource's limits.
143+
*
144+
* @param \Lomkit\Rest\Http\Requests\RestRequest $request
145+
*
146+
* @return array
147+
*/
148+
public function getLimits(\Lomkit\Rest\Http\Requests\RestRequest $request): array
149+
{
150+
$resolver = function () use ($request) {
151+
return $this->limits($request);
152+
};
153+
154+
if ($this->isResourceCacheEnabled()) {
155+
return Cache::remember(
156+
$this->getResourceCacheKey($request, 'limits'),
157+
$this->cacheResourceFor(),
158+
$resolver
159+
);
160+
}
161+
162+
return $resolver();
163+
}
90164
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Concerns\Resource;
4+
5+
trait DisableAuthorizationsCache
6+
{
7+
/**
8+
* Check if authorization cache is enabled for this resource.
9+
*
10+
* @return bool
11+
*/
12+
public function isAuthorizationCacheEnabled(): bool
13+
{
14+
return false;
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Concerns\Resource;
4+
5+
trait DisableResourceCache
6+
{
7+
/**
8+
* Check if resource cache is enabled for this resource.
9+
*
10+
* @return bool
11+
*/
12+
public function isResourceCacheEnabled(): bool
13+
{
14+
return false;
15+
}
16+
}

src/Concerns/Resource/Relationable.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Lomkit\Rest\Concerns\Resource;
44

55
use Illuminate\Support\Arr;
6+
use Illuminate\Support\Facades\Cache;
67
use Illuminate\Support\Str;
78
use Lomkit\Rest\Http\Requests\RestRequest;
89
use Lomkit\Rest\Relations\Relation;
@@ -100,8 +101,20 @@ public function relations(RestRequest $request): array
100101
*/
101102
public function getRelations(RestRequest $request)
102103
{
103-
return array_map(function (Relation $relation) {
104-
return $relation->fromResource($this);
105-
}, $this->relations($request));
104+
$resolver = function () use ($request) {
105+
return array_map(function (Relation $relation) {
106+
return $relation->fromResource($this);
107+
}, $this->relations($request));
108+
};
109+
110+
if ($this->isResourceCacheEnabled()) {
111+
return Cache::remember(
112+
$this->getResourceCacheKey($request, 'relations'),
113+
$this->cacheResourceFor(),
114+
$resolver
115+
);
116+
}
117+
118+
return $resolver();
106119
}
107120
}

src/Http/Requests/MutateRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function mutateRules(Resource $resource, $prefix = 'mutate.*', $loadedRel
4545
$prefix.'.attributes' => [
4646
'prohibited_if:'.$prefix.'.operation,attach',
4747
'prohibited_if:'.$prefix.'.operation,detach',
48-
new ArrayWith($resource->fields($this)),
48+
new ArrayWith($resource->getFields($this)),
4949
],
5050
$prefix.'.key' => [
5151
'required_if:'.$prefix.'.operation,update',

0 commit comments

Comments
 (0)