The Laminas API Tools uses the laminas/laminas-router package. This allows you to define segmented routes with placeholders as described in the laminas documentation for routing.
A good API maps only the CRUD (create, read, update and delete) operations via REST. Everything special that does not match CRUD operations I 'd do with a specialized RPC service. To keep it clean and simple just use one controler for one action per route to avoid oversized controllers. To be completely logical about this, I would suggest that you implement different services using the API tools. A REST service that handles the customer issues. A REST service that handles the concerns for the orders. A RPC service that delivers the orders of a specific customer.
In your module.config.php …
'router' => [
'application.rpc.customer-orders' => [
'type' => 'Segment',
'options' => [
'route' => '/customer/orders[/:customer_id]',
'defaults' => [
'controller' => 'Application\\V1\\Rpc\\CustomerOrders\\Controller',
'action' => 'listAction',
As you can see the route is defined as https://www.example.tld/customer/orders[/:customer_id]. In this case
[/:customer_id] is the placeholder for any id. If given, the parameter is forwarded by a slash.
In your controller …
class CustomerOrdersController extends AbstractActionController
public function listAction()
$customerId = $this->params()->fromRoute('customer_id', 0);
To get the given ID from the the route, you can use the parameter controller plugin, which is automatically active in any controller. In this example you fetch the customer id from route, where we defined
customer_id as route parameter. The second argument is a default fallback argument, which will be used, when there 's no customer given. As a result of this, you can check, if the customer id is 0 and get some error reporting done.
Summary: Define your route in the
module.config.php file and grab the defined parameters with the params controller plugin.