Initial API setup
This commit is contained in:
parent
72c0c37672
commit
0b0a4e9d69
9
src/api/.htaccess
Normal file
9
src/api/.htaccess
Normal file
@ -0,0 +1,9 @@
|
||||
RewriteEngine On
|
||||
|
||||
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
|
||||
RewriteRule ^(.*)$ - [E=BASE:%1]
|
||||
|
||||
RewriteRule ^recipes.db$ %{ENV_BASE}index.php [QSA,L]
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
|
50
src/api/app-setup.php
Normal file
50
src/api/app-setup.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
$container = $app->getContainer();
|
||||
|
||||
// Inject a Monolog logger into the dependency container
|
||||
$container['logger'] = function($c) {
|
||||
$logger = new Monolog\Logger('API');
|
||||
$fileHandler = new Monolog\Handler\StreamHandler('logs/api.log');
|
||||
|
||||
$logger->pushHandler($fileHandler);
|
||||
|
||||
return $logger;
|
||||
};
|
||||
|
||||
// Replace notFoundHandler to use an API response
|
||||
$container['notFoundHandler'] = function($c) {
|
||||
return function($request, $response) use ($c) {
|
||||
return $c['response']
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
->write('{ message: "Matching API call not found." }');
|
||||
};
|
||||
};
|
||||
|
||||
// Replace the errorHandler to use an API response
|
||||
$container['errorHandler'] = function ($c) {
|
||||
return function ($request, $response, $exception) use ($c) {
|
||||
$c['logger']->addError('Server error', $exception->getTrace());
|
||||
|
||||
return $c['response']->withStatus(500)
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
->write('{ message: "Internal Server Error", error: "' .
|
||||
$exception->getMessage() . '" }');
|
||||
};
|
||||
};
|
||||
|
||||
// Routes ending in '/' use route without '/'
|
||||
$app->add(function($request, $response, $next) {
|
||||
$uri = $request->getUri();
|
||||
$path = $uri->getPath();
|
||||
|
||||
if (strlen($path) > 1 && substr($path, -1) === '/') {
|
||||
$path = substr($path, 0, -1);
|
||||
}
|
||||
|
||||
if ($uri->getPath() !== $path) {
|
||||
return $next($request->withUri($uri->withPath($path)), $response);
|
||||
}
|
||||
|
||||
return $next($request, $response);
|
||||
});
|
||||
|
26
src/api/controllers/ApiJson.php
Normal file
26
src/api/controllers/ApiJson.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
class ApiJson {
|
||||
public $status = 'failure';
|
||||
public $data = [];
|
||||
public $alerts = [];
|
||||
|
||||
function setSuccess() {
|
||||
$this->status = 'success';
|
||||
}
|
||||
|
||||
function setFailure() {
|
||||
$this->status = 'failure';
|
||||
}
|
||||
|
||||
function addData($obj) {
|
||||
$this->data[] = $obj;
|
||||
}
|
||||
|
||||
function addAlert($type, $text) {
|
||||
$this->alerts[] = [
|
||||
'type' => $type,
|
||||
'text' => $text
|
||||
];
|
||||
}
|
||||
}
|
||||
|
15
src/api/controllers/BaseController.php
Normal file
15
src/api/controllers/BaseController.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
abstract class BaseController {
|
||||
protected $apiJson;
|
||||
protected $logger;
|
||||
|
||||
public function __construct($container) {
|
||||
$this->apiJson = new ApiJson();
|
||||
$this->logger = $container->get('logger');
|
||||
}
|
||||
|
||||
public function jsonResponse($response) {
|
||||
return $response->withJson($this->apiJson);
|
||||
}
|
||||
}
|
||||
|
24
src/api/controllers/Boards.php
Normal file
24
src/api/controllers/Boards.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
use RedBeanPHP\R;
|
||||
|
||||
class Boards extends BaseController {
|
||||
|
||||
public function getAllBoards($request, $response, $args) {
|
||||
$boardBeans = R::findAll('board');
|
||||
|
||||
if (count($boardBeans)) {
|
||||
$this->apiJson->setSuccess();
|
||||
|
||||
foreach($boardBeans as $bean) {
|
||||
$this->apiJson->addData(Board::fromBean($bean));
|
||||
}
|
||||
} else {
|
||||
$this->logger->addInfo('No boards in database.');
|
||||
$this->apiJson->addAlert('info', 'No boards in database.');
|
||||
}
|
||||
|
||||
return $this->jsonResponse($response);
|
||||
}
|
||||
|
||||
}
|
||||
|
21
src/api/controllers/Invalid.php
Normal file
21
src/api/controllers/Invalid.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
class Invalid extends BaseController {
|
||||
|
||||
public function noApi($request, $response, $args) {
|
||||
$this->apiJson->addAlert('error',
|
||||
'No API functionality at this endpoint.');
|
||||
|
||||
$apiReturn = new stdClass();
|
||||
$apiReturn->status = 'One of "success" or "failure".';
|
||||
$apiReturn->data = 'An array of data (JSON objects and/or arrays).';
|
||||
$apiReturn->alerts = 'An array of alerts, with "type" of "success", "error", "warn", or "info" and a "text" message.';
|
||||
|
||||
$this->apiJson->addData($apiReturn);
|
||||
|
||||
$this->logger->addInfo('Invalid Endpoint: ', [$this->apiJson]);
|
||||
|
||||
return $this->jsonResponse($response);
|
||||
}
|
||||
|
||||
}
|
||||
|
16
src/api/index.php
Normal file
16
src/api/index.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
require './vendor/autoload.php';
|
||||
|
||||
use RedBeanPHP\R;
|
||||
R::setup('sqlite:taskboard');
|
||||
|
||||
$app = new Slim\App();
|
||||
require 'app-setup.php';
|
||||
|
||||
$app->get('/', 'Invalid:noApi');
|
||||
|
||||
$app->get('/boards', 'Boards:getAllBoards');
|
||||
|
||||
$app->run();
|
||||
R::close();
|
||||
|
30
src/api/models/BaseModel.php
Normal file
30
src/api/models/BaseModel.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
use RedBeanPHP\R;
|
||||
|
||||
abstract class BaseModel {
|
||||
protected $logger;
|
||||
protected $bean;
|
||||
|
||||
public function __construct($type, $id) {
|
||||
global $app;
|
||||
$container = $app->getContainer();
|
||||
|
||||
$this->logger = $container->get('logger');
|
||||
$this->bean = R::load($type, $id);
|
||||
}
|
||||
|
||||
public abstract function updateBean();
|
||||
public abstract function loadFromBean($bean);
|
||||
|
||||
public function save() {
|
||||
$this->updateBean();
|
||||
R::store($this->bean);
|
||||
$this->loadFromBean($this->bean);
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
$this->updateBean();
|
||||
R::trash($this->bean);
|
||||
}
|
||||
}
|
||||
|
24
src/api/models/Board.php
Normal file
24
src/api/models/Board.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
class Board extends BaseModel {
|
||||
|
||||
public function __construct($id = 0, $internal = false) {
|
||||
parent::__construct('board', $id);
|
||||
|
||||
if ($internal) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->loadFromBean($this->bean);
|
||||
}
|
||||
|
||||
public static function fromBean($bean) {
|
||||
}
|
||||
|
||||
public function updateBean() {
|
||||
}
|
||||
|
||||
public function loadFromBean() {
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user