Plugins can be created to add REST endpoints to ProcessMaker in version 3.0.1.7 and later. Follow the steps below to create a new REST endpoint.

Create a plugin

The Gulliver framework is used to create new plugins in ProcessMaker. This tool exports and packages the new plugins, so they can be imported into other installations of ProcessMaker. Note that new plugins can only be developed in Linux/UNIX installations of ProcessMaker, but then they can be imported into Windows or Linux/UNIX installations.

The following steps describe how to create a plugin with Gulliver:

Login as root (or use the sudo command). Then, make a symbolic link between the gulliver/bin/gulliver directory and the workflow/engine directory:
# ln -s /opt/processmaker/gulliver/bin/gulliver /opt/processmaker/workflow/engine

Change to the /opt/processmaker/gulliver/bin/gulliver directory and execute the ./gulliver command to see a list of options: # cd /opt/processmaker/workflow/engine # ./gulliver

Then, create the new plugin:

# ./gulliver new-plugin pluginName

For example:

# ./gulliver new-plugin epSample

After executing this command, the script will ask a series of yes/no questions. Unless the new REST endpoint will need these features, type "N" to answer no to the following questions:

  1. Change system logo
  2. Create an example Page
  3. Create new option in the menu of cases
  4. Create the Role 'PROCESSMAKER_PLUGIN_NAME' and the Permission 'PM_PLUGIN_NAME'
  5. Create external step for Processmaker
  6. Create a PmFunction Class for extending Processmaker

When the plugin is created, its new files will be placed in an external plugins directory in the same location where ProcessMaker is installed. For example, if ProcessMaker is installed at /opt/processmaker and the new plugin is named epSample, then it will be located at /opt/plugins/epSample.

Copy the generated files to the /opt/processmaker/workflow/engine/plugins directory. For example:

# cp -r /opt/plugins/epSample /opt/processmaker/workflow/engine/plugins/

After this the two files must be inside folder /opt/processmaker/workflow/engine/plugins/:

Required Configuration to support REST Extension:

It is necessary to grant write permissions to the entire folder for development purposes. You can use the following command:

# chmod 777 -R /opt/processmaker/workflow/engine/plugins/

Then, edit the pluginName.php file and add the following code to the function in order to enable it to be accessed by REST:

$this->enableRestService(true);

It should look like this:

In order to define the REST endpoints for your plugin, create the following folder:
    /opt/processmaker/workflow/engine/plugins/pluginName/src/Services/Api/PluginName

Note that the first folder is the plugin name in camel case and the second folder is also in camel case with the first character in uppercase.

For example:

# mkdir -p /opt/processmaker/workflow/engine/plugins/epSample/src/Services/Api/EpSample

At this point you should have the following directory:

Then create the endpoints in a PHP file inside this directory. In our case, the file is named Sample.php.

Once it is saved, delete the route cache file:

# rm /opt/processmaker/shared/sites/workflow/routes.php

Then you will need to enable the plugin as usual.

Testing the new REST endpoint

The Postman extension in Chrome or HttpRequester add-on in Firefox can be used to send requests to the new REST endpoint, which is located at the address:
    {server-address}/api/1.0/{workspace}/{plugin-name}/{routed-path}

In our case the path is:
    http://127.0.0.1:3020/api/1.0/workflow/plugin-EpSample/sample/hello/{var}

Now you can check the response with Postman or HttpRequester.

Note: It may be necessary to re-enable the plugin within ProcessMaker each time the endpoint file has been modified.

REST endpoint creation

Supported Annotations:

You may use PHPDoc comments to annotate your API methods. All tags except @url, @param and @var can also be defined at the class level so that they will be applied for all the API methods. You can override them at method level individually when needed.

HTTP Methods:

@url GET|POST|PUT|PATCH|DELETE custom/{dynamic}/route

Access:

@access private|public|protected|hybrid

Smart routing:

@smart-auto-routing true|false

Parameters:

@param [type] Name [Description] {@name value}

For example:

This method is only recommended when you define a GET request. There is no need to define the route. Only define the class name.

//[HTTP_METHOD][function_name]
//example:
function postMethod($anyparameter, $parameter=optional)
{
    return "Post method called";
}
//POST request:
// Api/method/{parameter}

Notice that the HTTP method is defined along with the function name and the route for this method is in the path of the function name.

Parameters:

The function parameter definition can be optional as shown above.

Smart Auto routing:

It is also an automatic method, which allows all possible routes to be created for the function's defined parameters.

//smart-routing sample
/**
 * @smart-auto-routing true
 */

public function sRouting($p1, $p2, $p3='optional')
{
   return 'smart routing sample called parameters'.$p1.$p2.$p3;
}

Manual Routing

In this routing it is necessary to define the path and the HTTP method.

The URI (Uniform Resource Identifier) of the REST endpoint, which is its route, is created manually using a PHPDoc comment. We can specify as many routes as we want.

/**
 * Manually routed method. We can specify as many routes as we want.
 *
 * @url POST smanual
 * @url POST smanual/{param}
 * @url GET any/required/path
 */

public function whatEver($param)
{
    return 'Manual routed called'.$param;
}

Examples:

"GET" example

namespace Services\Api\epSample;
use ProcessMaker\Services\Api;
class Sample extends Api
{
    private $_keys;
    private $_values;
    function add($key, $value){
     $this->_keys[]=$key;
     $this->_values[]=$value;      
    }
    function __construct($key, $value){
        $this->keys[]=$key;
        $this->values[]=$value;
 
    }
    /**
     * @url GET /sample/new/:var/:content
     */

    public function newsample($var,$content)
    {  
        $s = new Sample("firstkey","secondvalue");
        $newarray=(array) $s;
        return $newarray;
    }

Note that the namespace is important in the REST endpoint PHP class.

"POST" example

    /**
     * @url POST /sample/new/{var}/{content}
     */

    public function newsample($var,$content)
    {  
        $s = new Sample();
        $newarray=(array) $s;
        return $newarray;
    }

"PUT" example

    /**
     * @url PUT /sample/new/{var}/{content}
     */

    public function newsample($var,$content) {  
        $s = new Sample();
        $newarray=(array) $s;
        return $newarray;
    }