Use the REST extension as boilerplate
This tutorial will show how the extension can be used as a starting point for custom web services. The core of the own web service is the Handler. The Handler implements the \Cundd\Rest\HandlerInterface
which provides the accessors to set and retrieve the current Request object and the method configureApiPaths()
.
You can find the tutorial extension under https://github.com/cundd/custom_rest. It uses namespaces and therefore requires at least TYPO3 version 6.0.
Configure the access
The following lines configure read and write access to all paths matching cundd-custom_rest-*
. This allows calls to your-domain.com/rest/cundd-custom_rest-route
, your-domain.com/rest/cundd-custom_rest-path
and your-domain.com/rest/cundd-custom_rest-whatever
.
plugin.tx_rest.settings.paths {
400 {
path = cundd-custom_rest-*
read = allow
write = allow
}
}
File: ext_typoscript_setup.txt
Configure an alias
The paths shown above are quite unesthetic, but enable the extensions flexibility. To still provide pretty URLs aliases can be registered.
plugin.tx_rest.settings.aliases {
customhandler = cundd-custom_rest-custom_handler
}
File: ext_typoscript_setup.txt
This allows us to call your-domain.com/rest/customhandler
instead of your-domain.com/rest/cundd-custom_rest-custom_handler
.
Creating the Handler
Now lets have a look at the core of the custom extension: the Handler. To ship a Handler with your extension create a class in the format \YourVendor\YourExtensionName\Rest\Handler
and make it implement \Cundd\Rest\HandlerInterface
. REST's Object Manager will then automatically use this class for any request which path matches cundd-custom_rest-*
.
The request accessor methods are used to make the current Request available to the Handler.
/**
* Current request
*
* @var Request
*/
protected $request;
/**
* Sets the current request
*
* @param \Cundd\Rest\Request $request
* @return $this
*/
public function setRequest($request) {
$this->request = $request;
return $this;
}
/**
* Returns the current request
*
* @return \Cundd\Rest\Request
*/
public function getRequest() {
return $this->request;
}
File: Handler.php
The more interesting method is configureApiPaths()
. Keep in mind that the REST extension is built with Bullet and this is the place where the actual routing is configured.
/**
* Configure the API paths
*/
public function configureApiPaths() {
$dispatcher = Dispatcher::getSharedDispatcher();
/** @var Handler */
$handler = $this;
$dispatcher->registerPath($dispatcher->getRequest()->path(), function ($request) use ($handler, $dispatcher) {
$handler->setRequest($request);
# curl -X GET http://your-domain.com/rest/customhandler
$dispatcher->registerGetMethod(function ($request) use ($dispatcher) {
/** @var Request $request */
return array(
'path' => $request->path(),
'uri' => $request->uri(),
);
});
$dispatcher->registerPath('subpath', function ($request) use ($handler, $dispatcher) {
# curl -X GET http://your-domain.com/rest/customhandler/subpath
$getCallback = function ($request) use ($handler, $dispatcher) {
/** @var Request $request */
return array(
'path' => $request->path(),
'uri' => $request->uri(),
);
};
$dispatcher->registerGetMethod($getCallback);
# curl -X POST -d '{"username":"johndoe","password":"123456"}' http://your-domain.com/rest/customhandler/subpath
$postCallback = function ($request) use ($handler) {
/** @var Request $request */
return array(
'path' => $request->path(),
'uri' => $request->uri(),
'data' => $request->getSentData(),
);
};
$dispatcher->registerPostMethod($postCallback);
});
});
}
The line $app->path($dispatcher->getPath(), function ... {
sets the scope of the following definitions to the current request's path (i.e. cundd-custom_rest-path
).
In the next line the current request will be stored in the Handlers request property (this is where the setRequest()
method is used).
Now lets define the first route:
$app->get(function ($request) {
instructs Bullet to execute the function when a GET
request on the Handlers path is performed (i.e. GET http://your-domain.com/rest/customhandler
). The function's return value will then be transformed into a response object of type \Bullet\Response
and i.e. an array will be passed through json_encode()
before.
$app->path('subpath', function ... {
narrows the scope to match your-domain.com/rest/cundd-custom_rest-custom_handler/subpath
, your-domain.com/rest/customhandler/subpath
, ... and the following $app->get($getCallback)
and $app->post($postCallback)
register the callbacks for the according HTTP methods.
To access the data sent by the client, the dispatcher provides the method getSentData()
which will return an array.
Finally the web service can be tested with
curl -X GET http://your-domain.com/rest/customhandler
curl -X GET http://your-domain.com/rest/customhandler/subpath
curl -X POST -H "Content-Type: application/json" -d '{"username":"johndoe","password":"123456"}' http://your-domain.com/rest/customhandler/subpath