Rework API to be more RESTful (references #139)

This commit is contained in:
Bernd Bestel
2019-01-19 14:51:51 +01:00
parent 0ce8d706a6
commit bfa59dd29c
52 changed files with 1110 additions and 1143 deletions

View File

@@ -18,10 +18,14 @@ class BaseApiController extends BaseController
return json_encode($data);
}
protected function VoidApiActionResponse($response, $success = true, $status = 200, $errorMessage = '')
protected function EmptyApiResponse($response, $status = 204)
{
return $response->withStatus($status);
}
protected function GenericErrorResponse($response, $errorMessage, $status = 400)
{
return $response->withStatus($status)->withJson(array(
'success' => $success,
'error_message' => $errorMessage
));
}

View File

@@ -16,20 +16,22 @@ class BatteriesApiController extends BaseApiController
public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$trackedTime = date('Y-m-d H:i:s');
if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time']) && IsIsoDateTime($request->getQueryParams()['tracked_time']))
{
$trackedTime = $request->getQueryParams()['tracked_time'];
}
$requestBody = $request->getParsedBody();
try
{
$trackedTime = date('Y-m-d H:i:s');
if (array_key_exists('tracked_time', $requestBody) && IsIsoDateTime($requestBody['tracked_time']))
{
$trackedTime = $requestBody['tracked_time'];
}
$chargeCycleId = $this->BatteriesService->TrackChargeCycle($args['batteryId'], $trackedTime);
return $this->ApiResponse(array('charge_cycle_id' => $chargeCycleId));
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -41,7 +43,7 @@ class BatteriesApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -55,11 +57,11 @@ class BatteriesApiController extends BaseApiController
try
{
$this->ApiResponse($this->BatteriesService->UndoChargeCycle($args['chargeCycleId']));
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@@ -16,26 +16,28 @@ class ChoresApiController extends BaseApiController
public function TrackChoreExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$trackedTime = date('Y-m-d H:i:s');
if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time']) && IsIsoDateTime($request->getQueryParams()['tracked_time']))
{
$trackedTime = $request->getQueryParams()['tracked_time'];
}
$doneBy = GROCY_USER_ID;
if (isset($request->getQueryParams()['done_by']) && !empty($request->getQueryParams()['done_by']))
{
$doneBy = $request->getQueryParams()['done_by'];
}
$requestBody = $request->getParsedBody();
try
{
$trackedTime = date('Y-m-d H:i:s');
if (array_key_exists('tracked_time', $requestBody) && IsIsoDateTime($requestBody['tracked_time']))
{
$trackedTime = $requestBody['tracked_time'];
}
$doneBy = GROCY_USER_ID;
if (array_key_exists('done_by', $requestBody) && !empty($requestBody['done_by']))
{
$doneBy = $requestBody['done_by'];
}
$choreExecutionId = $this->ChoresService->TrackChore($args['choreId'], $trackedTime, $doneBy);
return $this->ApiResponse(array('chore_execution_id' => $choreExecutionId));
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -47,7 +49,7 @@ class ChoresApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -61,11 +63,11 @@ class ChoresApiController extends BaseApiController
try
{
$this->ApiResponse($this->ChoresService->UndoChoreExecution($args['executionId']));
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@@ -30,11 +30,11 @@ class FilesApiController extends BaseApiController
$data = $request->getBody()->getContents();
file_put_contents($this->FilesService->GetFilePath($args['group'], $fileName), $data);
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -61,12 +61,12 @@ class FilesApiController extends BaseApiController
}
else
{
return $this->VoidApiActionResponse($response, false, 404, 'File not found');
return $this->GenericErrorResponse($response, 'File not found', 404);
}
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -89,11 +89,11 @@ class FilesApiController extends BaseApiController
unlink($filePath);
}
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@@ -12,7 +12,7 @@ class GenericEntityApiController extends BaseApiController
}
else
{
return $this->VoidApiActionResponse($response, false, 400, 'Entity does not exist or is not exposed');
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
}
}
@@ -24,7 +24,7 @@ class GenericEntityApiController extends BaseApiController
}
else
{
return $this->VoidApiActionResponse($response, false, 400, 'Entity does not exist or is not exposed');
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
}
}
@@ -44,16 +44,16 @@ class GenericEntityApiController extends BaseApiController
$newRow = $this->Database->{$args['entity']}()->createRow($requestBody);
$newRow->save();
$success = $newRow->isClean();
return $this->ApiResponse(array('success' => $success));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
else
{
return $this->VoidApiActionResponse($response, false, 400, 'Entity does not exist or is not exposed');
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
}
}
@@ -73,16 +73,16 @@ class GenericEntityApiController extends BaseApiController
$row = $this->Database->{$args['entity']}($args['objectId']);
$row->update($requestBody);
$success = $row->isClean();
return $this->ApiResponse(array('success' => $success));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
else
{
return $this->VoidApiActionResponse($response, false, 400, 'Entity does not exist or is not exposed');
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
}
}
@@ -93,11 +93,11 @@ class GenericEntityApiController extends BaseApiController
$row = $this->Database->{$args['entity']}($args['objectId']);
$row->delete();
$success = $row->isClean();
return $this->ApiResponse(array('success' => $success));
return $this->EmptyApiResponse($response);
}
else
{
return $this->VoidApiActionResponse($response, false, 400, 'Entity does not exist or is not exposed');
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}

View File

@@ -17,7 +17,7 @@ class RecipesApiController extends BaseApiController
public function AddNotFulfilledProductsToShoppingList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$this->RecipesService->AddNotFulfilledProductsToShoppingList($args['recipeId']);
return $this->VoidApiActionResponse($response);
return $this->EmptyApiResponse($response);
}
public function ConsumeRecipe(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
@@ -25,11 +25,11 @@ class RecipesApiController extends BaseApiController
try
{
$this->RecipesService->ConsumeRecipe($args['recipeId']);
return $this->VoidApiActionResponse($response);
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@@ -22,7 +22,7 @@ class StockApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -34,107 +34,155 @@ class StockApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function AddProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$bestBeforeDate = date('Y-m-d');
if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate']) && IsIsoDate($request->getQueryParams()['bestbeforedate']))
{
$bestBeforeDate = $request->getQueryParams()['bestbeforedate'];
}
$price = null;
if (isset($request->getQueryParams()['price']) && !empty($request->getQueryParams()['price']) && is_numeric($request->getQueryParams()['price']))
{
$price = $request->getQueryParams()['price'];
}
$transactionType = StockService::TRANSACTION_TYPE_PURCHASE;
if (isset($request->getQueryParams()['transactiontype']) && !empty($request->getQueryParams()['transactiontype']))
{
$transactionType = $request->getQueryParams()['transactiontype'];
}
$requestBody = $request->getParsedBody();
try
{
$bookingId = $this->StockService->AddProduct($args['productId'], $args['amount'], $bestBeforeDate, $transactionType, date('Y-m-d'), $price);
if ($requestBody === null)
{
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
}
if (!array_key_exists('amount', $requestBody))
{
throw new \Exception('An amount is required');
}
$bestBeforeDate = date('Y-m-d');
if (array_key_exists('best_before_date', $requestBody) && IsIsoDate($requestBody['best_before_date']))
{
$bestBeforeDate = $requestBody['best_before_date'];
}
$price = null;
if (array_key_exists('price', $requestBody) && is_numeric($requestBody['price']))
{
$price = $requestBody['price'];
}
$transactionType = StockService::TRANSACTION_TYPE_PURCHASE;
if (array_key_exists('transaction_type', $requestBody) && !empty($requestBody['transactiontype']))
{
$transactionType = $requestBody['transactiontype'];
}
$bookingId = $this->StockService->AddProduct($args['productId'], $requestBody['amount'], $bestBeforeDate, $transactionType, date('Y-m-d'), $price);
return $this->ApiResponse(array('booking_id' => $bookingId));
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function ConsumeProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$spoiled = false;
if (isset($request->getQueryParams()['spoiled']) && !empty($request->getQueryParams()['spoiled']) && $request->getQueryParams()['spoiled'] == '1')
{
$spoiled = true;
}
$transactionType = StockService::TRANSACTION_TYPE_CONSUME;
if (isset($request->getQueryParams()['transactiontype']) && !empty($request->getQueryParams()['transactiontype']))
{
$transactionType = $request->getQueryParams()['transactiontype'];
}
$specificStockEntryId = "default";
if (isset($request->getQueryParams()['stock_entry_id']) && !empty($request->getQueryParams()['stock_entry_id']))
{
$specificStockEntryId = $request->getQueryParams()['stock_entry_id'];
}
$requestBody = $request->getParsedBody();
try
{
$bookingId = $this->StockService->ConsumeProduct($args['productId'], $args['amount'], $spoiled, $transactionType, $specificStockEntryId);
if ($requestBody === null)
{
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
}
if (!array_key_exists('amount', $requestBody))
{
throw new \Exception('An amount is required');
}
$spoiled = false;
if (array_key_exists('spoiled', $requestBody))
{
$spoiled = $requestBody['spoiled'];
}
$transactionType = StockService::TRANSACTION_TYPE_CONSUME;
if (array_key_exists('transaction_type', $requestBody) && !empty($requestBody['transactiontype']))
{
$transactionType = $requestBody['transactiontype'];
}
$specificStockEntryId = 'default';
if (array_key_exists('stock_entry_id', $requestBody) && !empty($requestBody['stock_entry_id']))
{
$specificStockEntryId = $requestBody['stock_entry_id'];
}
$bookingId = $this->StockService->ConsumeProduct($args['productId'], $requestBody['amount'], $spoiled, $transactionType, $specificStockEntryId);
return $this->ApiResponse(array('booking_id' => $bookingId));
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function InventoryProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$bestBeforeDate = date('Y-m-d');
if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate']) && IsIsoDate($request->getQueryParams()['bestbeforedate']))
{
$bestBeforeDate = $request->getQueryParams()['bestbeforedate'];
}
$requestBody = $request->getParsedBody();
try
{
$bookingId = $this->StockService->InventoryProduct($args['productId'], $args['newAmount'], $bestBeforeDate);
if ($requestBody === null)
{
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
}
if (!array_key_exists('new_amount', $requestBody))
{
throw new \Exception('An new amount is required');
}
$bestBeforeDate = date('Y-m-d');
if (array_key_exists('best_before_date', $requestBody) && IsIsoDate($requestBody['best_before_date']))
{
$bestBeforeDate = $requestBody['best_before_date'];
}
$bookingId = $this->StockService->InventoryProduct($args['productId'], $requestBody['new_amount'], $bestBeforeDate);
return $this->ApiResponse(array('booking_id' => $bookingId));
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
public function OpenProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$specificStockEntryId = "default";
if (isset($request->getQueryParams()['stock_entry_id']) && !empty($request->getQueryParams()['stock_entry_id']))
{
$specificStockEntryId = $request->getQueryParams()['stock_entry_id'];
}
$requestBody = $request->getParsedBody();
try
{
$bookingId = $this->StockService->OpenProduct($args['productId'], $args['amount'], $specificStockEntryId);
if ($requestBody === null)
{
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
}
if (!array_key_exists('amount', $requestBody))
{
throw new \Exception('An amount is required');
}
$specificStockEntryId = 'default';
if (array_key_exists('stock_entry_id', $requestBody) && !empty($requestBody['stock_entry_id']))
{
$specificStockEntryId = $requestBody['stock_entry_id'];
}
$bookingId = $this->StockService->OpenProduct($args['productId'], $requestBody['amount'], $specificStockEntryId);
return $this->ApiResponse(array('booking_id' => $bookingId));
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -164,13 +212,13 @@ class StockApiController extends BaseApiController
public function AddMissingProductsToShoppingList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$this->StockService->AddMissingProductsToShoppingList();
return $this->VoidApiActionResponse($response);
return $this->EmptyApiResponse($response);
}
public function ClearShoppingList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$this->StockService->ClearShoppingList();
return $this->VoidApiActionResponse($response);
return $this->EmptyApiResponse($response);
}
public function ExternalBarcodeLookup(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
@@ -187,7 +235,7 @@ class StockApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -196,11 +244,11 @@ class StockApiController extends BaseApiController
try
{
$this->ApiResponse($this->StockService->UndoBooking($args['bookingId']));
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}

View File

@@ -30,11 +30,11 @@ class SystemApiController extends BaseApiController
$requestBody = $request->getParsedBody();
$this->LocalizationService->LogMissingLocalization(GROCY_CULTURE, $requestBody['text']);
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@@ -21,20 +21,22 @@ class TasksApiController extends BaseApiController
public function MarkTaskAsCompleted(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{
$doneTime = date('Y-m-d H:i:s');
if (isset($request->getQueryParams()['done_time']) && !empty($request->getQueryParams()['done_time']) && IsIsoDateTime($request->getQueryParams()['done_time']))
{
$doneTime = $request->getQueryParams()['done_time'];
}
$requestBody = $request->getParsedBody();
try
{
$doneTime = date('Y-m-d H:i:s');
if (array_key_exists('done_time', $requestBody) && IsIsoDateTime($requestBody['done_time']))
{
$doneTime = $requestBody['done_time'];
}
$this->TasksService->MarkTaskAsCompleted($args['taskId'], $doneTime);
return $this->VoidApiActionResponse($response);
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}

View File

@@ -22,7 +22,7 @@ class UsersApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -38,11 +38,11 @@ class UsersApiController extends BaseApiController
}
$this->UsersService->CreateUser($requestBody['username'], $requestBody['first_name'], $requestBody['last_name'], $requestBody['password']);
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -51,11 +51,11 @@ class UsersApiController extends BaseApiController
try
{
$this->UsersService->DeleteUser($args['userId']);
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -66,11 +66,11 @@ class UsersApiController extends BaseApiController
try
{
$this->UsersService->EditUser($args['userId'], $requestBody['username'], $requestBody['first_name'], $requestBody['last_name'], $requestBody['password']);
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -83,7 +83,7 @@ class UsersApiController extends BaseApiController
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
@@ -94,11 +94,11 @@ class UsersApiController extends BaseApiController
$requestBody = $request->getParsedBody();
$value = $this->UsersService->SetUserSetting(GROCY_USER_ID, $args['settingKey'], $requestBody['value']);
return $this->ApiResponse(array('success' => true));
return $this->EmptyApiResponse($response);
}
catch (\Exception $ex)
{
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
}