Skip to content
Hufschmidt edited this page May 5, 2015 · 9 revisions

ILIAS REST Plugin extensions can be used to enlarge and customize the API for your ILIAS installation in order to enable Restful webservices.

Installing an existing extension

At current, a template extension is hosted at https://github.com/disc5/RESTPluginTemplate.

We are considering at current a place where extensions can be exchanged. If you have ideas or if you developed extensions that you want to share with the ILIAS community please let us know.

The procedure of installing an extension is simple. Copy the folder <extension_name> from the repository to the plugin folder REST/RESTController/extensions/<extension_name>.

Developing a new extension

The anatomy of an extension

An extension consists of two parts: a controller and a model. A controller defines REST endpoints and for each rest endpoint the controller is responsible to process an incoming request, prepare and send an answer to the client. In order to enable reusable and testable code, the business logic is bundled as much as possible in model classes.

Thus a controller invokes one or multiple model methods to combine, evaluate and transforming the resulting data into an output format, which by default is json. Models often encapsulate database access or code involving ILIAS objects.

Folder structure

The template (https://github.com/disc5/RESTPluginTemplate) provides a prototypical implementation for an extension. It provides examplary REST endoints for the typical Create-Read-Update-Delete (CRUD) operations. The folder structure for each extension is the same:

  ── extension_name
    ├── models
    │   │   // One or multiple PHP class files with the suffix php.
    │   └── extension_name_model1.php
    ├── routes
    │   │   // One or multiple files defining SLIM routes aka controllers
    │   └── extension_name_routes.php
    │
    │   // Optional. Allows for describing the extension API in human readable format
    ├── apidoc.html
    │   // For documentation purposes (purpose, features, contact, changelog,...)
    └── README.md

Securing an endpoint

In the following, we use interchangeably the terms REST endpoint and SLIM route. There are two principle options to treat a SLIM route. The first option is not to secure a route at all. And the second option is to apply a middleware function that is invoked before the code of a route is being executed. By using middleware functions one is able to control access to a route.
The ILIAS REST plugin provides some middleware functions located at REST/RESTController/libs/AuthMiddleware.php:

  • \RESTController\libs\AuthMiddleware::authenticate Checks if the user supplied a valid access-token and has permission to execute this action (GET, POST, etc.) on this route (eg. /clients). An access-token is valid if it contains all required data see TokenLib) and hasn't expired.
  • \RESTController\libs\AuthMiddleware::authenticateTokenOnly Only checks if the user supplied a valid acces-token.
  • \RESTController\libs\AuthMiddleware::authenticateILIASAdminRole Checks if the user supplied a valid access-token and the user that is stored inside the access-token has the admin-role in ILIAS.
  • Or no user authentication.

Since user-information is stored inside the access-token, if for any user-related data is required you need to use one of the above authentification middlewares. Once a user was authenticated using the access-token, the data can be accessed inside your route or model using:

$app = \Slim\Slim::getInstance();
$env = $appp->environment();
//$env ['user'], $env ['api_key'], $env ['token'] will be available now

Examples

  1. Using the authenticate middleware function to secure an endpoint.

$app->get('/v1/users', '\RESTController\libs\AuthMiddleware::authenticate', function () use ($app) { ... });

  1. Using no middleware function at all.

$app->get('/items', function () use ($app) { ... });

The $app variable is provided (locally) to all routes (that use the suggested folder-layout) via the RESTControllers run()-Method. Make sure to use function () use ($app) { ... } if you want easy access to the RESTController application inside a route.

Dependencies between Extensions

It is possible to use the models of another extension inside any other controller or model, because all models are loaded "on-demand".
This structure allows for dealing with following two scenarios (see diagram):

  1. If extensions A and B are located within the same installation:
    1.1 It is possible that extension A can use the routes defined by extension B.
    1.2 It is possible that the controller of extension A can use models defined in extension B.
  2. If extensions A and B are located at different installations, then extension A can make use of the functionality of extension B only through the provided endpoints defined by extension B ,i.e. by an API call.

Examples

Example for scenario 1:
Reusing the code from another extension model, e.g. to provide more functionality.

Example for scenario 2:
Cloning a file from installation 1 to installation 2.

Further Information

In Addition, when implementing a new Extensions it is advisable to read the Information the following pages:

  • Take a look at the general Design of the REST Plugin, most importanly the sections about Namespaces, Environment and Request/Response handling. This should give some feedback on how to best integrate the Extension into the REST Plugin.
  • Feel free to read the Information on Code-Conventions. Since PHP is prone to allow bad design, this should help detect and prevent commonn pitfalls.