-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a944993
commit 96b85c9
Showing
1 changed file
with
310 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,310 @@ | ||
<?php namespace CodeIgniter\API; | ||
|
||
/** | ||
* Class ResponseTrait | ||
* | ||
* Provides common, more readable, methods to provide | ||
* consistent HTTP responses under a variety of common | ||
* situations when working as an API. | ||
* | ||
* @property $response CodeIgniter\HTTP\Response | ||
* | ||
* @package CodeIgniter\API | ||
*/ | ||
trait ResponseTrait | ||
{ | ||
/** | ||
* Allows child classes to override the | ||
* status code that is used in their API. | ||
* | ||
* @var array | ||
*/ | ||
protected $codes = [ | ||
'created' => 201, | ||
'deleted' => 200, | ||
'invalid_request' => 400, | ||
'unsupported_response_type' => 400, | ||
'invalid_scope' => 400, | ||
'temporarily_unavailable' => 400, | ||
'invalid_grant' => 400, | ||
'invalid_credentials' => 400, | ||
'invalid_refresh' => 400, | ||
'no_data' => 400, | ||
'invalid_data' => 400, | ||
'access_denied' => 401, | ||
'unauthorized' => 401, | ||
'invalid_client' => 401, | ||
'forbidden' => 403, | ||
'resource_not_found' => 404, | ||
'not_acceptable' => 406, | ||
'resource_exists' => 409, | ||
'conflict' => 409, | ||
'resource_gone' => 410, | ||
'payload_too_large' => 413, | ||
'unsupported_media_type' => 415, | ||
'too_many_requests' => 429, | ||
'server_error' => 500, | ||
'unsupported_grant_type' => 501, | ||
'not_implemented' => 501 | ||
]; | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Provides a single, simple method to return an API response, formatted | ||
* to match the requested format, with proper content-type and status code. | ||
* | ||
* @param null $data | ||
* @param int $status | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function respond($data=null, int $status=200, string $message='') | ||
{ | ||
// If data is null and status code not provided, exit and bail | ||
if ($data === null && $status === null) | ||
{ | ||
$status = 404; | ||
|
||
// Create the output var here in case of $this->response([]); | ||
$output = null; | ||
} | ||
|
||
// If data is null but status provided, keep the output empty. | ||
elseif ($data === null && is_numeric($status)) | ||
{ | ||
$output = null; | ||
} | ||
else | ||
{ | ||
$output = $this->format($data); | ||
} | ||
|
||
return $this->response->setBody($output) | ||
->setStatusCode($status, $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used for generic failures that no custom methods exist for. | ||
* | ||
* @param $messages | ||
* @param int|null $status | ||
* @param string $customMessage | ||
* | ||
* @return mixed | ||
*/ | ||
public function fail($messages, int $status=400, string $customMessage='') | ||
{ | ||
if (! is_array($messages)) | ||
{ | ||
$message = [$messages]; | ||
} | ||
|
||
$response = [ | ||
'error' => $status, | ||
'messages' => $messages | ||
]; | ||
|
||
return $this->respond($response, $status, $customMessage); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
//-------------------------------------------------------------------- | ||
// Response Helpers | ||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used after successfully creating a new resource. | ||
* | ||
* @param $data | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function respondCreated($data, string $message='') | ||
{ | ||
return $this->respond($data, $this->codes['created'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used after a resource has been successfully deleted. | ||
* | ||
* @param $data | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function respondDeleted($data, string $message='') | ||
{ | ||
return $this->respond($data, $this->codes['deleted'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used when the client is either didn't send authorization information, | ||
* or had bad authorization credentials. User is encouraged to try again | ||
* with the proper information. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failUnauthorized(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['unauthorized'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used when access is always denied to this resource and no amount | ||
* of trying again will help. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failForbidden(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['forbidden'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used when a specified resource cannot be found. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failNotFound(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['resource_not_found'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used when the data provided by the client cannot be validated. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failValidationError(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['invalid_data'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Use when trying to create a new resource and it already exists. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failResourceExists(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['resource_exists'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Use when a resource was previously deleted. This is different than | ||
* Not Found, because here we know the data previously existed, but is now gone, | ||
* where Not Found means we simply cannot find any information about it. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failResourceGone(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['resource_gone'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Used when the user has made too many requests for the resource recently. | ||
* | ||
* @param string $description | ||
* @param string $message | ||
* | ||
* @return mixed | ||
*/ | ||
public function failTooManyRequests(string $description, string $message='') | ||
{ | ||
return $this->fail($description, $this->codes['too_many_requests'], $message); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
|
||
//-------------------------------------------------------------------- | ||
// Utility Methods | ||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Handles formatting a response. Currently makes some heavy assumptions | ||
* and needs updating! :) | ||
* | ||
* @param null $data | ||
* | ||
* @return null|string | ||
*/ | ||
protected function format($data = null) | ||
{ | ||
// If the data is a string, there's not much we can do to it... | ||
if (is_string($data)) | ||
{ | ||
$this->setContentType('html'); | ||
return $data; | ||
} | ||
|
||
// @todo Implement a formatting library so we have other options | ||
$this->setContentType('json'); | ||
return json_encode($data); | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
|
||
/** | ||
* Sets the response's content type. If a type is permitted | ||
* ('html', 'json', or 'xml'), the appropriate content type is set. | ||
* | ||
* @param string $type | ||
*/ | ||
protected function setContentType(string $type=null) | ||
{ | ||
switch ($type) | ||
{ | ||
case 'html': | ||
$this->response->setContentType('text/html'); | ||
break; | ||
case 'json': | ||
$this->response->setContentType('application/json'); | ||
break; | ||
case 'xml': | ||
$this->response->setContentType('text/xml'); | ||
break; | ||
} | ||
} | ||
} |