Skip to content

Commit

Permalink
[#8] Add a basic public API
Browse files Browse the repository at this point in the history
and a status page to demo it
  • Loading branch information
danmichaelo committed Feb 6, 2019
1 parent bcee3e2 commit 28b5604
Show file tree
Hide file tree
Showing 21 changed files with 667 additions and 44 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ NodeJS:

npm run watch

#### Update OpenAPI documentation for Swagger UI:

./vendor/bin/openapi app -o public/openapi.json

#### Refreshing the database

Disable logging to database when refreshing the database:
Expand Down
176 changes: 176 additions & 0 deletions app/Http/Controllers/PublicApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<?php

namespace App\Http\Controllers;

use App\Http\Resources\ItemCollection;
use App\Http\Resources\LibraryCollection;
use App\Http\Resources\ThingCollection;
use App\Item;
use App\Library;
use App\Thing;
use Illuminate\Http\Request;

/**
* @OA\Info(
* title="Bibrex",
* version="0.1.0"
* )
*/
class PublicApiController extends Controller
{
protected function doc()
{
return response()->view('apidoc');
}

/**
* @OA\Get(
* path="/api/libraries",
* summary="List libraries",
* description="Get a list of libraries.",
* tags={"Libraries"},
* @OA\Response(
* response=200,
* description="success"
* )
* )
*
* @param Request $request
* @return LibraryCollection
*/
protected function libraries(Request $request)
{
$resources = Library::query()
->orderBy('name')
->get();

return new LibraryCollection($resources);
}

/**
* @OA\Get(
* path="/api/things",
* summary="List things",
* description="Get a list of things.",
* tags={"Things"},
* @OA\Response(
* response=200,
* description="success"
* ),
* @OA\Parameter(
* name="library",
* in="query",
* description="Filter by library ID. The item counts will also reflect the selected library.",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="items",
* in="query",
* description="Include list of items for each thing.",
* @OA\Schema(
* type="boolean"
* )
* ),
* @OA\Parameter(
* name="name",
* in="query",
* description="Filter by name, case-insensitive, truncate with '*'",
* @OA\Schema(
* type="string"
* )
* )
* )
*
* @param Request $request
* @return ThingCollection
*/
protected function things(Request $request)
{
$query = Thing::with('settings');

if ($request->items && strtolower($request->items) !== 'false') {
$query->with([
'items' => function ($query) use ($request) {
if (isset($request->library)) {
$query->where('library_id', '=', $request->library);
}
},
// Check if item is available or not.
'items.loans' => function ($query) use ($request) {
$query->orderBy('created_at')->limit(1);
},
]);
$query->with('items.library');
}

if (isset($request->library)) {
$query->whereHas('items', function ($itemQuery) use ($request) {
$itemQuery->where('library_id', '=', $request->library);
});
}

if (isset($request->name)) {
$query->where('name', 'ilike', str_replace('*', '%', $request->name));
}

$resources = $query
->orderBy('name')
->get();

return new ThingCollection($resources);
}

/**
* @OA\Get(
* path="/api/items",
* summary="List items",
* description="Get a list of items. Only non-deleted items are returned.",
* tags={"Items"},
* @OA\Response(
* response=200,
* description="success"
* ),
* @OA\Parameter(
* name="library",
* in="query",
* description="Filter by library ID.",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="thing",
* in="query",
* description="Filter by thing ID.",
* @OA\Schema(
* type="integer"
* )
* )
* )
*
* @param Request $request
* @return ItemCollection
*/
protected function items(Request $request)
{
$query = Item::query();

$query->with('thing');

if (isset($request->library)) {
$query->where('library_id', '=', $request->library);
}

if (isset($request->thing)) {
$query->where('thing_id', '=', $request->thing);
}

$resources = $query
->orderBy('barcode')
->get();

return new ItemCollection($resources);
}
}
37 changes: 0 additions & 37 deletions app/Http/Controllers/ThingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,43 +114,6 @@ public function json(Request $request)
return response()->json($things);
}

/**
* Display a listing of the resource.
*
* @param Library $library
* @return Response
*/
public function getAvailableJson(Library $library)
{
$things = Thing::with('items.loans')
->where('library_id', null)
->orWhere('library_id', $library->id)
->get();

$out = [];
foreach ($things as $t) {
$out[] = [
'name' => $t->name,
'available_items' => $t->availableItems(),
];
}

return response()->json($out);
}

/**
* Display a listing of the resource.
*
* @param Library $library
* @return Response
*/
public function getAvailable(Library $library)
{
return response()->view('things.available', [
'library_id' => $library->id,
]);
}

/**
* Display the specified resource.
*
Expand Down
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Kernel extends HttpKernel
'api' => [
'throttle:60,1',
'bindings',
\Barryvdh\Cors\HandleCors::class,
],

'webhooks' => [
Expand Down
26 changes: 26 additions & 0 deletions app/Http/Resources/ItemCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ItemCollection extends ResourceCollection
{
/**
* The resource that this resource collects.
*
* @var string
*/
public $collects = ItemResource::class;

/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}
32 changes: 32 additions & 0 deletions app/Http/Resources/ItemResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ItemResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'type' => 'item',
'id' => $this->id,
'barcode' => $this->barcode,
'note' => $this->note,
'created_at' => $this->created_at->toDateTimeString(),
'updated_at' => $this->updated_at->toDateTimeString(),

'thing' => ThingResource::make($this->whenLoaded('thing')),
'library' => LibraryResource::make($this->whenLoaded('library')),

// If 'loans' is eager-loaded, this will only require one query.
'available' => count($this->loans) === 0,
];
}
}
26 changes: 26 additions & 0 deletions app/Http/Resources/LibraryCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class LibraryCollection extends ResourceCollection
{
/**
* The resource that this resource collects.
*
* @var string
*/
public $collects = LibraryResource::class;

/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}
25 changes: 25 additions & 0 deletions app/Http/Resources/LibraryResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class LibraryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'type' => 'library',
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at->toDateTimeString(),
'updated_at' => $this->updated_at->toDateTimeString(),
];
}
}
26 changes: 26 additions & 0 deletions app/Http/Resources/ThingCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ThingCollection extends ResourceCollection
{
/**
* The resource that this resource collects.
*
* @var string
*/
public $collects = ThingResource::class;

/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}
Loading

0 comments on commit 28b5604

Please sign in to comment.