Skip to content

Endpoints ​

Under the hood, the endpoint path will be used to create a ProcessWire URL hook. All URL hook features are supported.

Each endpoint listener must either return a Response object or throw an ApiException to halt the process and respond with an error.

INFO

By default, all the request methods are denied, except for OPTIONS. You must add listeners for each request method you want to allow. Requests with disallowed methods will be denied with a 405 response that includes an Allow header listing the permitted methods.

The OPTIONS method is always allowed for existing endpoints and will result in an empty response with a status code of 200. The response includes an Allow header listing the permitted methods.

The supported listeners are:

  • get()
  • post()
  • head()
  • put()
  • patch()
  • delete()

Like an API instance or service, an endpoint can also contain request hooks. Read more about request hooks.

Example endpoint ​

Call addEndpoint() in the service init() method and pass the path you want to listen to.

php
use PwJsonApi\ApiException;
php
$this->addEndpoint('/user')
  // Handle GET request
  ->get(function () {
    return new Response([
      'first_name' => 'Jerry',
      'last_name' => 'Cotton',
    ]);
  })

  // Handle PUT request
  ->put(function ($args) {
    $body = $args->request->body;

    // Sanitize input
    $firstName = $this->wire->sanitizer->text($body['first_name'] ?? '');
    $lastName = $this->wire->sanitizer->text($body['last_name'] ?? '');

    // Validate required fields
    if (empty($firstName)) {
      throw new ApiException('First name is required.');
    }

    if (empty($lastName)) {
      throw new ApiException('Last name is required.');
    }

    // Save user details...

    // Respond with updated data
    return (new Response([
      'first_name' => $firstName,
      'last_name' => $lastName,
    ]))->with(['message' => 'User details saved successfully!']);
  });

Endpoint handler arguments ​

You can access the following properties via the $args parameter of the handler function.

PropertyTypeDescription
requestRequestRequest object
user\ProcessWire\UserThe current ProcessWire user
event\ProcessWire\HookEventProcessWire URL hook event
endpointEndpointRequested endpoint ^2.5
serviceServiceRequested service ^2.5
servicesServiceListList of all parent services ^2.5
apiApiAPI instance ^2.5
php
$this->addEndpoint('/test-request')->get(function ($args) {
  return new Response([
    'request_path' => $args->request->path,
    'request_method' => $args->request->method,
  ]);
});

Dynamic paths ​

You can use named arguments to allow dynamic paths. Use $args->request->routeParam() to access named arguments. Endpoint paths support all features provided by ProcessWire URL path hooks, including optional segments and regex constraints.

php
$this->addEndpoint('/animals/{animal}')->get(function ($args) {
  return new Response([
    'animal_name' => $args->request->routeParam('animal'),
  ]);
});

Querying /animals/bunny-rabbit results in a following JSON:

json
{
  "data": {
    "animal_name": "bunny-rabbit"
  }
}

Argument names are case-insensitive in routeParam(). ^2.5

Path case

By default, endpoint paths are lowercased. Since ProcessWire matches URLs case-sensitively, a path defined as /Products only responds to /products. Lowercasing also changes the meaning of regex patterns — for example, \D (non-digit) becomes \d (digit).

Enable the preservePathCase configuration option to use paths exactly as defined. This will be the default in 3.0. ^2.5

Released under the MIT License.