Creating a REST API in PHP to Fetch and Compress JSON Data with caching system
Tags: php, json, api, tutorial
Published: 2023-04-22 17:24:42



To create a REST API in PHP that fetches data from a JSON file and returns it in a compressed format, you can follow these steps:

1. Read the JSON data from the file:
```php
$data = file_get_contents('data.json');
```

2. Parse the JSON data:
```php
$json = json_decode($data, true);
```

3. Compress the JSON data using gzip:
```php
$compressed = gzencode(json_encode($json));
```

4. Set the appropriate response headers to indicate that the response is a JSON file and that it is compressed using gzip:
```php
header('Content-Type: application/json');
header('Content-Encoding: gzip');
```

5. Return the compressed JSON data:
```php
echo $compressed;
```

Here's the complete code for your reference:

```php
<?php
$data = file_get_contents('data.json');
$json = json_decode($data, true);
$compressed = gzencode(json_encode($json));
header('Content-Type: application/json');
header('Content-Encoding: gzip');
echo $compressed;
?>
```

With this implementation, the data will be compressed using gzip, which will reduce the amount of data transferred over the network, leading to faster response times and lower bandwidth usage.

### Caching data
To integrate a caching system that caches the `data.json` file and avoids fetching it every time the PHP API is called, you can use a technique called "conditional GET requests" using the `ETag` and `If-None-Match` headers.

Here's how you can modify the code to include caching:

```php
<?php
$filename = 'data.json';
$etag = md5_file($filename); // calculate the ETag of the file
header("ETag: $etag");

// check if the client has a cached copy of the file
if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag){
    header("HTTP/1.1 304 Not Modified");
    exit();
}

// if the client doesn't have a cached copy, read the file and generate the response
$data = file_get_contents($filename);
$json = json_decode($data, true);
$compressed = gzencode(json_encode($json));

// set the appropriate response headers
header('Content-Type: application/json');
header('Content-Encoding: gzip');
header('Cache-Control: max-age=3600'); // cache the response for 1 hour

// return the compressed JSON data
echo $compressed;
?>
```

With this implementation, the `ETag` header is set to the MD5 hash of the `data.json` file. When a client sends a GET request to the API, it includes the `If-None-Match` header with the ETag value of its cached copy. If the ETag value matches the ETag of the current file, the server sends a `304 Not Modified` response, indicating that the client can use its cached copy. Otherwise, the server generates a new response and sends it along with the new ETag value.

The `Cache-Control` header is also set to `max-age=3600`, which tells the client to cache the response for 1 hour.

With this caching implementation, the `data.json` file will only be read and compressed when it has been modified, saving bandwidth and server resources.

### Caching Method 2

To integrate a caching system that will cache the `data.json` file and avoid unnecessary reads every time the PHP API is called, you can use PHP's built-in caching functions like `apc_fetch` or `memcache`.

Here's an example implementation using `apc_fetch`:

```php
<?php
// Check if data is cached
if (apc_exists('data_json')) {
    $data = apc_fetch('data_json');
} else {
    // Read data from file
    $data = file_get_contents('data.json');
    // Store data in cache for 1 hour
    apc_store('data_json', $data, 3600);
}

// Parse JSON data
$json = json_decode($data, true);

// Compress JSON data using gzip
$compressed = gzencode(json_encode($json));

// Set appropriate headers
header('Content-Type: application/json');
header('Content-Encoding: gzip');

// Return compressed JSON data
echo $compressed;
?>
```

In this implementation, the `apc_fetch` function checks if the `data_json` key is present in the cache. If it is, the data is fetched from the cache. If not, the data is read from the file and stored in the cache with a time-to-live (TTL) of 1 hour. This means that subsequent requests within the TTL will fetch the data from the cache instead of reading it from the file.

Note: The `apc` extension has been removed in PHP 7.0.0, so you may want to use an alternative caching method like `memcache` or `redis` if you are using a PHP version greater than 7.0.0.

### Prettify the JSON

If you want to prettify the JSON response before returning it, you can use the `JSON_PRETTY_PRINT` option of the `json_encode` function. This option will add indentation and line breaks to the JSON output, making it more human-readable.

Here's an updated example implementation that prettifies the JSON response:

```php
<?php
// Check if data is cached
if (apc_exists('data_json')) {
    $data = apc_fetch('data_json');
} else {
    // Read data from file
    $data = file_get_contents('data.json');
    // Store data in cache for 1 hour
    apc_store('data_json', $data, 3600);
}

// Parse JSON data
$json = json_decode($data, true);

// Prettify JSON data
$pretty_json = json_encode($json, JSON_PRETTY_PRINT);

// Compress JSON data using gzip
$compressed = gzencode($pretty_json);

// Set appropriate headers
header('Content-Type: application/json');
header('Content-Encoding: gzip');

// Return compressed JSON data
echo $compressed;
?>
```

In this updated implementation, the `json_encode` function is called with the `JSON_PRETTY_PRINT` option to prettify the JSON output. The prettified JSON data is then compressed using gzip and returned to the client.

With this implementation, the JSON response will be easier to read and understand for human users.