Nette REST library
Smart and tiny implementation of REST API for Nette framework, (*1)
Content
- Requirements
- Installation
- Configuration
- Authentication
- Routing and presenters
- Examples
- Patrons
Requirements
For full requirements list please see this file, (*2)
Installation
The best way to install flame\tiny-rest is using Composer, (*3)
$ composer require flame/tiny-rest:@dev
and register extension:, (*4)
extensions:
rest: Flame\Rest\DI\RestExtension
Configuration
This package provide next options:, (*5)
-
authenticators
- list of classes implements Flame\Rest\Security\IAuthenticator
for authentication requests.
-
cors
- List of settings for cross-domain requests
-
origin
- list of allowed origins, or *
for all
-
headers
- list of allowed headers, or *
for all
-
methods
- list of allowed methods, or *
for all
-
ips
- list of allowed IP address, or nothing for allow all
-
referers
- list of allowed referers, or nothing for allow all
Example configuration:, (*6)
tinyRest:
cors:
origin: *
headers: *
methods: *
authenticators:
- My\Super\Authenticator
Authentication
This package provide several authorization method., (*7)
- Authorization by IP address - this authorization is enabled automatically when you set
ips
option in config file.
- Authorization by HTTP referer - this authorization is enabled automatically when you set
referers
option in config file
- Authentication by settings for cross-domain requests - this authorization is automatically enabled when you set
cors
option in config file and respects this rules
Next authorization methods is token-based authorization. For this authorization type you must do some steps:, (*8)
- You can create own authenticator implements
Flame\Rest\Security\IAuthenticator
or you can use default authenticator from this package
- You must create own token provider class implements
Flame\Rest\Security\Tokens\ITokenProvider
. This class with getToken()
must get token from request (request is provided as argument) and create and return a new instance of Flame\Rest\Security\Tokens\IToken
(there you must create own implementation or you can use default)
- You must create own implementation of
Flame\Rest\Security\Tokens\ITokenManager
wឧich provides method for validate token and getting identity for concrete token.
Implementation you can see in Examples., (*9)
Routing and presenters
Routing
This package provides one basic route:, (*10)
$router = new RouteList();
$router[] = new RestRoute('Api:V1');
return $router;
This route has one optional argument with module path for searching presenter. In this example expects models with names Api and V1., (*11)
Structure of URLs which is created by this router is /<module>/<presenter>[/<specific_action>][/<id>]
. For our example will be /api/v1/<presenter>[/<specific_action>][/<id>]
, (*12)
All this URLs is mapped to actions in presenter by rule action<create|update|read|readAll|delete><specific_action>(<id>)
when POST
= create
, PUT
= update
, DELETE
= delete
, GET
without id = readAll
and GET
with id = read
. For example:, (*13)
-
GET /api/v1/accounts
-> actionReadAll()
-
GET /api/v1/accounts/1
-> actionRead($id)
-
GET /api/v1/accounts/disabled/1
-> actionReadDisabled($id)
Presenter
All API presenters should be extended from RestPresenter
. When you can send data you must it write into resource
:, (*14)
public function actionRead($id) {
$this->resource->id = $id;
$this->resource->name = 'John';
}
or for better works you can use data
property of resource
, (*15)
public function actionRead($id) {
$this->resource->data = [
'id' => $id,
'name' => 'John'
];
}
Sending responses is automatically on end of action method with HTTP code 200. When you can change it, you must call sendResource($code)
manually., (*16)
public function actionRead($id) {
$this->resource->data = [
'id' => $id,
'name' => 'John'
];
$this->sendResource(500);
}
And for processing and logging errors you can use sendErrorResponse
method., (*17)
You can get data from POST, or query by input
or getInput()
member. You can get query values by getQuery()
, POST
values by getData()
or FILES
by getFiles()
, (*18)
public function actionReadAll() {
$limit = $this->getInput()->getQuery('limit');
$this->resource->data = [
'id' => $,
'name' => 'John'
];
$this->sendResource(500);
}
Examples
Router:, (*19)
$router = new RouteList();
$router[] = new RestRoute('Api:V1');
return $router;
Presenter AccountsPresenter.php, (*20)
class AccountsPresenter extends RestPresenter
{
/** User @inject */
public $user;
/**
* @User loggedIn
*/
public function actionReadAll()
{
$this->resource->data = $user->getIdentity();
}
}
Create own Token implementation:, (*21)
class Token implements IToken
{
private $token;
public function __construct($token)
{
$this->token = $token;
}
public function getToken()
{
return this->token;
}
}
Create a own TokenGetter:, (*22)
class TokenGetter implements ITokenGetter
{
public function getToken(Request $request)
{
return new Token($request->getHeader('Authorozation'));
}
}
Create own TokenManager, (*23)
class TokenManager implements ITokenManager
{
private $sessionManager;
public function __construct(SessionManager $sessionManager)
{
$this->sessionManager = $sessionManager;
}
public function isTokenValid(IToken $token)
{
$item = $this->sessionManager->getSessionByToken($token->getToken());
return $item['expiration'] < new \DateTime();
}
public function getIdentity(IToken $token)
{
$item = $this->sessionManager->getSessionByToken($token->getToken());
return $item['identity'];
}
}
In this example when I send GET
request on /api/v1/accounts
with Authorization: valid
header and use BasicAuthenticator
for authenticate by @User
annotation API returns identity of logged user., (*24)
Patrons
Big thanks to these guys!
* Ondra Zaruba (aka @budry), (*25)