@ -8,11 +8,59 @@ This component must be publicly visible in the internet, so it's important to ca
## Architecture
## Architecture
Web API is written in PHP using [Nette framework](https://nette.org/en/). This framework provides useful components like _Tracy_ for logging and showing errors, _Tester_ for productive unit testing or _Latte_ templating engine. Nette is modern, widely used and great performing software with active developers and user community. Nette can help eliminate security holes, simplify debugging and make coding easier with numerous plugins and extensions. Also, it's published under permissive BSD license.
API architecture consists of several parts:
- **router** -- component handling mapping from URL addresses to methods in presenter classes (called endpoints)
- **presenters** -- classes containing one method per endpoint responsible for fetching and parsing request arguments and performing desired action
- **entities** -- classes mirroring database tables, which are generated by ORM plugin
- **repositories** -- common operations on entities of one type, mostly finding entity by identifier or persisting changes to the database
- **helpers** -- set of classes solving more complicated internal logic, used from presenters to keep them reasonably small
Each presenter method has several annotations. They are used for generating REST API documentation in [Swagger](http://swagger.io/), specifying request type and it's parameters and specifying one level of access restrictions. Also, there is simple description of the endpoint.
For specifying the request type (_GET_, _POST_, _DELETE_) are used annotations with exactly these names without parameters. To describe request parameters is used `@Param` annotation with following arguments:
- type -- the type of argument, one of _post_ of _query_
- name -- name of the argument (the key)
- validation -- validation of the value, see [Nette validation rules](https://doc.nette.org/en/2.4/validators#toc-rules)
- msg -- description for users about the values this parameter can contain
- required -- specifies if this option is mandatory (`true`, default) or optional (`false`)
- description -- description for documentation of the API
Another annotation is `@LoggedIn` which takes no arguments. It can be placed before whole class or before a method, so requests from unauthorized users are forbidden. Permissions can be granted or prohibitted by `@UserIsAllowed` annotation. This one is only per method and takes one argument in format `key="value"`. The value specifies which action (_value_) of a resource (_key_) user need to be allowed to perform this request. Example how an annotated endpoint can look like:
Authorization of users is based on validating his access token, which is obtained by users on successful login. This token has predefined validity period and has to be renewed before expiration to stay logged in. The token is sent to the API in HTTP Authorization header as value in format `Bearer <token>`. Requests with invalid or malformed token are treated as anonymous access with all its restrictions.
As [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) framework is used [Doctrine](https://github.com/Kdyby/Doctrine). It provides some simple to use annotations to specify collumns of database tables including types, indexes and also it's possible to make mapping between entities. For detailed info refer to [official documentation](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/).
The API is capable of sending email messages. They can inform administrator about errors and users about submission evaluation or temporary link to change forgotten password. The [Nette Mail](https://doc.nette.org/en/2.4/mailing) extension provides nice interface for sending messages through external SMTP server (**preferred**) or builtin PHP function `mail`. It's important to set up the mailserver properly to ensure message delivery to the clients. The messages are rendered in HTML format via simple _Latte_ templates.
## Installation
## Installation
The web API requires a PHP runtime version at least 7. Which one depends on actual configuration, there is a choice between _mod_php_ inside Apache, _php-fpm_ with Apache or Nginx proxy or running it as standalone uWSGI script. Common thing is, that there are some PHP extensions, that have to be installed on the system. It's ZeroMQ binding (`php-zmq` package or similar), MySQL module (`php-mysqlnd` package) and ldap extension module for CAS authentication (`php-ldap` package). Make sure that the extensions are loaded in your `php.ini` file (`/etc/php.ini` or files in `/etc/php.d/`).
The web API requires a PHP runtime version at least 7. Which one depends on actual configuration, there is a choice between _mod_php_ inside Apache, _php-fpm_ with Apache or Nginx proxy or running it as standalone uWSGI script. Common thing is, that there are some PHP extensions, that have to be installed on the system. It's ZeroMQ binding (`php-zmq` package or similar), MySQL module (`php-mysqlnd` package) and ldap extension module for CAS authentication (`php-ldap` package). Make sure that the extensions are loaded in your `php.ini` file (`/etc/php.ini` or files in `/etc/php.d/`).
The API depends on some other projects and libraries. For managing them is used [Composer](https://getcomposer.org/). It can be installed from system repositories or downloaded from the website, where are also detailed instructions. Composer reads `composer.json` file in project root and install dependencies to `vendor/` subdirectory. To do that, run
The API depends on some other projects and libraries. For managing them is used [Composer](https://getcomposer.org/). It can be installed from system repositories or downloaded from the website, where are also detailed instructions. Composer reads `composer.json` file in project root and install dependencies to `vendor/` subdirectory. To do that, run: