Trongate Way Docs

The API Controller

The API controller lives in its own module: countries_api. It follows the same Trongate controller pattern but returns JSON instead of rendering views. There are no $this->view() calls, no templates, and no HTML - every method echoes a JSON-encoded response and sets an appropriate HTTP status code.

Module Structure

modules/countries_api/
  Countries_api.php          (controller)
  Countries_api_model.php    (model)
  logs/
    api_requests.log         (request audit log)

The Controller Skeleton

PHP
<?php
class Countries_api extends Trongate {

    public function get_all(): void {
        $this->authenticate();
        // ... fetch and return all countries
    }

    public function get_one(): void {
        $this->authenticate();
        // ... fetch and return a single country
    }

    public function create(): void {
        $this->authenticate();
        // ... create a new country
    }

    public function update(): void {
        $this->authenticate();
        // ... update an existing country
    }

    public function destroy(): void {
        $this->authenticate();
        // ... delete a country
    }

}

Every public method corresponds to one API endpoint. In this chapter, we focus on the get_all() and get_one() endpoints. In the next chapters we add create(), update(), and destroy().

Key Design Decisions

No Views, No Templates

Unlike the countries controller from the Basic CRUD chapter, this controller never calls $this->view() or $this->templates->admin(). Instead, every endpoint:

  1. Calls $this->authenticate() to verify the token
  2. Fetches or manipulates data via the model
  3. Calls http_response_code() to set the status code
  4. Echoes json_encode() to return structured data
  5. Calls $this->log_request() for auditing

Using block_url() for Helper Methods

The helper methods - authenticate(), log_request(), get_post_data(), and validate() - are all declared as public methods, but each one calls block_url() as its first action. This follows the Trongate v2 convention of keeping methods accessible from code while preventing direct URL invocation.

PHP
public function authenticate(): void {
    block_url('countries_api/authenticate');

    $token = $this->trongate_tokens->attempt_get_valid_token();

    if ($token === false) {
        http_response_code(401);
        echo json_encode(['error' => 'Unauthorized. A valid API token is required.']);
        die();
    }
}

Your Security, Your Rules. In this chapter we apply authenticate() to every endpoint, but that is a design choice, not a requirement. Trongate gives you the token system; you decide which endpoints need it. You may wish to leave get_all() public for fast browsing while requiring a token for create(), update(), and destroy(). The framework makes either approach straightforward.

For a full understanding of how tokens work, see Understanding Trongate's Token System in the framework documentation.

JSON Response Pattern

Every endpoint follows the same response pattern. Here is the simplest example, from get_all():

PHP
public function get_all(): void {
    $this->authenticate();

    $rows = $this->model->get_all();

    if (empty($rows)) {
        http_response_code(200);
        echo json_encode([]);
        return;
    }

    http_response_code(200);
    echo json_encode($rows);
}

Note that we return an empty array [] with a 200 status when there are no records - not an error. An empty collection is a valid response. An error would be something like a missing authentication token or an invalid record ID.

Next Step

With the controller skeleton in place, we will fill in the get_all() endpoint in the next page.

We're continually improving the Trongate documentation. If anything is incorrect, unclear, incomplete, or could be better, we'd genuinely appreciate your input.

Share your thoughts in the Documentation Feedback.

Leave Feedback About This Page