Configuration Options

Do not make changes to the distributed configuration file. Rather, include the distributed configuration file in your own configuration file and overwrite the items that you would like to. This eases the upgrade path when defaults are changed and new features are added.

The configuration variable is an associative array containing the following keys and values:

api_version

$config['api_version'] => '0.1.0.empty-dumpty'

The API version string allowing a userbase to keep track of API changes. It is definied as major.minor.maintenance[.build] where:

Major:Increase for each changes that may affect or not be compatible with a previous version of the API. Bumping the major generally imply a fresh new production deployment so the previous version can (and should) be left intact for those that depend upon it.
Minor:Increases each time there are new addition e.g. a new resource.
Maintenance:Increases each time there are modifications to existing resource entities and which don’t break exisiting definitions.
Build:Can be use for arbitrary naming such as 0.1.0.beta, 0.1.1.rc3 (third release candidate), 0.1.2.smoking-puma, 0.1.30.testing

api_realm

$config['api_realm'] => 'api.example.com'

The API realm name. Used in few places, most notably as part of the version string in the header response. It is also used as part of some authentication mechanisms e.g. Basic and Digest. Should always be a generic/static string and cannot be used to define server instance. In other words, DO NOT use $_SERVER[‘SERVER_NAME’] to set this option!

output_rootNode

$config['output_rootNode'] => 'apix'

Define the name of the data output topmost node which contains the various nodes generated by the response output. The signature and debug nodes are also contained within this node if they are enabled in the plugins section.

input_formats

$config['input_formats'] => array('post', 'json', 'xml')

The array of available data formats for input representation:

POST:Body post data
JSON:Light text-based open standard designed for human-readable data interchange.
XML:Generic and standard markup language as defined by XML 1.0 schema.

Note that at this stage only UTF-8 is supported.

routing

The routing value is an associative array with the following keys: path_prefix, formats, default_format, http_accept, controller_ext, and format_override.

$config['routing'] => array(
    'path_prefix' => ...,
    'formats' => ...,
    'default_format' => ...,
    'http_accept' => ...,
    'controller_ext' => ...,
    'format_override' => ...
);

path_prefix

'path_prefix' => '/-(\/\w+\.\w+)?(\/api)?\/v(\d+)/i'

The regular expression representing the path prefix from the Request-URI. Allows the server to retrieve the path without the route prefix, handling variation in version numbering, Apache’s mod_rewrite, nginx location definitions, etc...

Should match ‘/index.php/api/v1/entity/name?whatver...’ which using mod_rewrite could then translate into ‘http://www.example.com/v1/entity/name?whatver...’.

formats

'formats' => array('json', 'xml', 'jsonp', 'html', 'php')

The array of available data formats for output representation:

JSON:Light text-based open standard designed for human-readable data interchange.
XML:Generic and standard markup language as defined by the XML 1.0 specification. Again, other schema could be implemented if required.
JSONP:Output JSON embeded within a javascript callback. Javascript clients can set the callback name using the GET/POST variable named ‘callback’ or default to the ‘output_rootNode’ value set above.
HTML:Output an HTML bulleted list.
PHP:Does not currently serialize the data as one would expect but just dumps the output array for now.

default_format

'default_format' => 'json'

Set the defaut output format to either JSON or XML. Note that JSON encoding is by definition UTF-8 only. If a specific encoding is required then XML should be used as the default format. In most case, JSON is favored.

http_accept

'http_accept' => true

Whether to enable the negotiation of output format from an HTTP Accept header. This is the expected and most RESTful way to set the output format. See RFC 2616 for more information.

controller_ext

'controller_ext' => true

Whether to allow the output format to be set from the Request-URI using a file extension such as ‘/controller.json/id’. This is handy and common practice but fairly un-RESTful. The extension overrides the http_accept negotiation.

format_override

'format_override' => isset($_REQUEST['_format']) ? $_REQUEST['_format'] : false

Forces the output format to the string provided and overrides the format negotiation process. Set to false to disable. Can be use to set the format from a request parameter, or any other arbitrary methods, etc... Using $_REQUEST is considered un-RESTful but also can be handy in many cases e.g. forms handling.

resources

A resource definition is made of a ‘Route path’ (with or without named variable) pointing to a controller which may be defined as closure/lambda definitions (à la Sinatra) allowing fast prototyping, class definitions allowing for a tradition Model + Controller layout, or a redirect.

Class Definitions

$config['resources'] += array(
    '/hello/:name' => array(
        'controller' => array(
            'name' =>   'MyControllers\Hello', // a namespace\classname as a string
            'args' =>   array('classArg1'=>'value1', 'classArg2'=>'string') // a __constructor variables as an array or null.
        )
    ),
    ...
)

The default values to the ‘resources’ key set up API documentation links and should not be overwritten.

Redirects

$config['resources'] += array(
    '/redirect/me' => array(
        'redirect' => '/hello/world'
    ),
    ...
)

Perform a redirect on the path ‘/redirect/me’ to ‘hello/world’.

services

The service defintions array is mostly used as a convenient container to define some generic/shared code. For example, Authorization adapters and session data can be stored in the services array. These items can later be retrieved using Apix\Service::get().

Authentication Service Example

An example Authentication service might look something like this:

$config['services'] => array(
    // $config is the current configuration array
    'auth' => function() use ($config) {
        // Example implementing Plugin\Auth\Basic
        // The Basic Authentification mechanism is generally used with SSL.
        $adapter = new Apix\Plugin\Auth\Basic($config['api_realm']);
        $adapter->setToken(function(array $current) {
            $users = array(
                array('username'=>'example', 'password'=>'mypassword', group=>'admin', 'realm'=>'www.example.com')
            );
            foreach ($users as $user) {
                if ($current['username'] == $user['username'] && $current['password'] == $user['password']) {
                    Service::get('session', $user);
                    return true;
                }
            }
            return false;
        });
        return $adapter;
    },

    // create a session object that we can use in the auth service
    'session' => function($user) {
        // Set that way solely to avoid duplicating code in auth_example.
        $session = new Session($user['username'], $user['group']);
        // Overwrite this service container, with the new Session object!
        // Apix\Plugin\Auth expects this session container to hold Apix\Session.
        Service::set('session', $session);
    }
);

In this example, we have both a session service and an auth service. The auth service makes use of the session service, as the session is used in other code in APIx. Another service might have been created to store or dynamically retrieve a users array.

plugins

Please see the Plugin documentation for more information on available event hooks and interface for Plugins.

Plugins is an associative array where each plugin is definied using the plugins class name as the key, and an array defining options for that plugin as the value. The options array is passed into the constructor for the specified plugin class. For example:

$config['plugins'] => array(
    'MyProject\Plugins\MyPlugin' => array('enable'=>true, 'myoption'=>'hello world')
);

The above code would create a new MyProject\Plugins\MyPlugin like this:

$plugin = new \MyProject\Plugins\MyPlugin(array('enable'=>true, 'myoption'=>'hello world'));

Currently available plugins include the following:

Output Signature

Adds the entity signature as part of the response body.

$config['plugins']['Apix\\Plugin\\OutputSign'] = array();

Output Debugging

Add some debugging information within the response body. This should be set to false in production and does have an impact on cachability.

$config['plugins']['Apix\\Plugin\\OutputDebug'] = array();

Tidy (Pretty-print)

Validates, corrects, and pretty-prints XML and HTML outputs. Various options are available. See the Tidy quickref for more information on available options.

$config['plugins']['Apix\\Plugin\\Tidy'] = array('indent-spaces' => 4, 'indent' => true);

Authentication

The authentication plugin is enabled through method/closure annotation. The following example instructs the authentication plugin allow access to the following GET resource if a user can authenticate to either the “admin” or “default” user groups.

/**
 * My Method Annotation
 * @api_auth  groups=admin,default  users=usera,userb
 **/
public function onRead() {
    ...
}

The configuration block must provide an adapter object which implements Apix\Plugin\\Auth\\Adapter. An Authentication Service Example which provides an authentication adapter is included in the Services section.

$config['plugins']['Apix\\Plugin\\Auth'] = array('adapter' => $c['services']['auth']);

Entity Caching

The cache plugin allows you to easily cache the output from a controller request. The full Request-URI acts as the unique cache id for a particular resource. Like the authorization plugin, this is enabled through method/closure annotation. For example:

/**
 * My Method Annotation
 * @api_cache  ttl=1hours  tags=tag1,tag2  flush=tag3,tag4
 **/
public function onRead() {
    ...
}

Apix\Cache is available at https://github.com/frqnck/apix-cache.

The options available for the cache plugin include an “enable” key and an “adapter” key, which requires an object implementing an Apix\Cache\Adapter interface.

$config['plugins']['Apix\Plugin\Cache'] = array(
    'enable'  => true,
    'adapter' => new Apix\Cache\APC
);

You could also add the caching adapter as a services to reuse the same cache connection throughout your project. In that case, instead of instantiating a new Apix\Cache\APC in your plugin configuration, you would create a service that exposes the adapter, and use that. For example:

$config['services']['cache'] = new Apix\Cache\APC;

$config['plugins']['Apix\Plugin\Cache'] = array(
    'enable' => true,
    'adapter' => $config['services']['cache']
);

init

Init is an associative array of specific PHP directives. They are recommended settings for most generic REST API servers and should be set as required. There is most probably a performance penalty setting most of these at runtime so it is recommneded that most, if not all, of these be set directly in php.ini/vhost files on productions servers and then commented out. Values included here will overwrite the values provided in php.ini or other PHP init files.

display_errors

'display_errors' => true

Whether to display errors or not. This should be set to false in production.

init_log_errors

'init_log_errors' => true

Enable or disable php error logging.

error_log

'error_log' => '/path/to/error.log'

Path to the error log file.

html_errors

'html_errors' => true

Enable or disable html_errors.

zlib.output_compression

'zlib.output_compression' => true

Whether to transparently compress outputs using GZIP. If enabled, this options will also add a ‘Vary: Accept-Encoding’ header to response objects.

memory_limit

'memory_limit' => '64M'

Maximum amount of memory a script may consume.

max_execution_time

'max_execution_time' => 15

The timeout in seconds. Be aware that web servers such as Apache also have their own timout settings that may interfere with this. See your web server manual for specific details.

post_max_size

'post_max_size' => '8M'

Maximum size of POST data that this script will accept. Its value may be 0 to disable the limit.

max_input_time

'max_input_time' => 30

Maximum amount of time each script may spend parsing request data.

max_input_vars

'max_input_vars' => 100

Maximum number of GET/POST input variables.

max_input_nesting_level

'max_input_nesting_level' => 64

Maximum input variable nesting level.

variables_order

'variables_order' => 'GPS'

Determines which super global are registered and in which order these variables are then populated. G,P,C,E & S are abbreviations for the following respective super globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty paid for the registration of these arrays and because ENV is not as commonly used as the others, ENV is not recommended on productions servers. You can still get access to the environment variables through getenv() should you need to.

request_order

'request_order' => 'GP'

This directive determines which super global data (G,P,C,E & S) should be registered into the super global array REQUEST. If so, it also determines the order in which that data is registered. The values for this directive are specified in the same manner as the variables_order directive, EXCEPT one. Leaving this value empty will cause PHP to use the value set in the variables_order directive. It does not mean it will leave the super globals array REQUEST empty.