Skip to content

Commit

Permalink
Initial rest api support
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmitchell committed Nov 3, 2023
1 parent 7a843fa commit 8dbfd65
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/Http/Controllers/RestApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace DoubleThreeDigital\Runway\Http\Controllers;

use DoubleThreeDigital\Runway\Http\Resources\ApiResource;
use DoubleThreeDigital\Runway\Resource;
use DoubleThreeDigital\Runway\Runway;
use Facades\Statamic\API\FilterAuthorizer;
use Illuminate\Support\Str;
use Statamic\Exceptions\NotFoundHttpException;
use Statamic\Http\Controllers\API\ApiController;

class RestApiController extends ApiController
{
private $config;
protected $resourceConfigKey = 'runway';
protected $routeResourceKey = 'resource';
protected $resourceHandle;

public function index($resource)
{
$this->abortIfDisabled();

$this->resourceHandle = $resource;

$resource = Runway::findResource($resource);

if (! $resource) {
throw new NotFoundHttpException;
}

$results = $this->filterSortAndPaginate($resource->model()->query());
$results->setCollection($results->getCollection()->map(fn ($model) => $this->makeResourceFromModel($resource, $model)));

return ApiResource::collection($results);
}

public function show($resource, $id)
{
$this->abortIfDisabled();

$this->resourceHandle = $resource;

$resource = Runway::findResource($resource);

if (! $resource) {
throw new NotFoundHttpException;
}

if (! $model = $resource->model()->find($id)) {
throw new NotFoundHttpException;
}

return ApiResource::make($this->makeResourceFromModel($resource, $model));
}

protected function allowedFilters()
{
return FilterAuthorizer::allowedForSubResources('api', $this->resourceConfigKey, $this->resourceHandle);
}

private function makeResourceFromModel($resource, $model)
{
if (! $this->config) {
$this->config = collect(config('runway.resources'))->get(get_class($model));
}

return new Resource(
handle: $this->resourceHandle,
model: $model,
name: $this->config['name'] ?? Str::title($this->resourceHandle),
blueprint: $resource->blueprint(),
config: $this->config ?? [],
);
}
}
22 changes: 22 additions & 0 deletions src/Http/Resources/ApiResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace DoubleThreeDigital\Runway\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ApiResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return $this->resource
->toAugmentedCollection()
->withShallowNesting()
->toArray();
}
}
28 changes: 28 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

namespace DoubleThreeDigital\Runway;

use DoubleThreeDigital\Runway\Http\Controllers\RestApiController;
use DoubleThreeDigital\Runway\Policies\ResourcePolicy;
use DoubleThreeDigital\Runway\Search\Provider as SearchProvider;
use DoubleThreeDigital\Runway\Search\Searchable;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Traits\Conditionable;
use Statamic\API\Middleware\Cache;
use Statamic\Facades\CP\Nav;
use Statamic\Facades\GraphQL;
use Statamic\Facades\Permission;
use Statamic\Facades\Search;
use Statamic\Http\Middleware\API\SwapExceptionHandler as SwapAPIExceptionHandler;
use Statamic\Http\Middleware\RequireStatamicPro;
use Statamic\Providers\AddonServiceProvider;
use Statamic\Statamic;

Expand Down Expand Up @@ -80,6 +85,7 @@ public function boot()
$this->registerPolicies();
$this->registerNavigation();
$this->bootGraphQl();
$this->bootRestApi();

SearchProvider::register();
$this->bootModelEventListeners();
Expand Down Expand Up @@ -151,6 +157,28 @@ protected function bootGraphQl()
GraphQL::addQuery("runway_graphql_queries_{$resource->handle()}_show");
});
}

protected function bootRestApi()
{
if (config('statamic.api.enabled')) {
Route::middleware([
SwapApiExceptionHandler::class,
RequireStatamicPro::class,
Cache::class,
])->group(function () {
Route::middleware(config('statamic.api.middleware'))
->name('statamic.api.')
->prefix(config('statamic.api.route'))
->group(function () {
Runway::allResources()
->each(function (Resource $resource) {
Route::name('runway.'.$resource->handle().'.index')->get('runway/{resource}', [RestApiController::class, 'index']);
Route::name('runway.'.$resource->handle().'.show')->get('runway/{resource}/{id}', [RestApiController::class, 'show']);
});
});
});
}
}

protected function bootModelEventListeners()
{
Expand Down

0 comments on commit 8dbfd65

Please sign in to comment.