• The following patch to JSON API 1.1.1 adds two settings:

    • Caching of all JSON responses for a specified amount of seconds
    • Benchmarking (showing time spent in the end of every response)

    Caching is done with WordPress Transient API. Responses are served from cache only for requests that are identical (where the serialized $_REQUEST array in PHP is identical).

    Benefits

    The degree of speedup depends mainly on how heavy the operation is to process. In our testing the speedup varied between 20x for displaying a list of categories and 350x for displaying more than 500 Events Manager events with their locations, categories and other data. With the benchmarking option you can easily measure the difference for your use case.

    The patch below also adds the standard notices to the admin page when changing settings and displays a warning when trying to use an incorrect value for the cache duration.

    Implementation

    In singletons/api.php change lines 58-59 from

    // Run the method
    	        $result = $this->controller->$method();

    to

    // Set up caching and benchmarking
            $cache_duration = get_option('json_api_cache_duration', 0);
            $requested = array( $_REQUEST, $_SERVER['REQUEST_URI'] );
            $request_md5 = md5( json_encode( $requested ) );
            $benchmarking = get_option('json_api_benchmarking', false);
            $time_start = microtime(true);
            $cached = true;
    
            // If caching enabled, attempt to retrieve result from cache. Evaluates to true when fails
            if ($cache_duration == 0 || false === ( $result = get_transient('json_api_' . $request_md5))) {
                $cached = false;
                // Run the method
                $result = $this->controller->$method();
                // If caching enabled, save the result
                if ($cache_duration > 0) {
                    set_transient('json_api_' . $request_md5, $result, $cache_duration);
                }
            }
    
            // Display benchmarking results if enabled
            $time_difference = microtime(true) - $time_start;
            if ($benchmarking) {
                $result['benchmarking'] = "Response generated in $time_difference seconds " . ( $cached ? "from" : "without" ) . " cache.";
            }

    and change line 114-117 from

    }
    	      if (isset($_REQUEST['json_api_base'])) {
    	        $this->save_option('json_api_base', $_REQUEST['json_api_base']);
    	      }

    to

    $updated = true;
          }
          if (isset($_REQUEST['json_api_base']) && $_REQUEST['json_api_base'] != get_option('json_api_base')) {
            $this->save_option('json_api_base', $_REQUEST['json_api_base']);
            $updated = true;
          }
          if (isset($_REQUEST['json_api_cache_duration'])) {
            // Check whether value contains only numbers
            if (preg_match('_^[0-9]+$_', $_REQUEST['json_api_cache_duration'])) {
              $this->save_option('json_api_cache_duration', $_REQUEST['json_api_cache_duration']);
              $updated = true;
            } else if ( $_REQUEST['json_api_cache_duration'] == '') {
              if (get_option('json_api_cache_duration') != 0) {
                $this->save_option('json_api_cache_duration', 0);
                $updated = true;
              }
            } else {
              ?><div class="error">Caching time value can contain only numbers (0-9).</div><?php
            }
          }
          if (isset($_REQUEST['json_api_benchmarking'])) {
            $this->save_option('json_api_benchmarking', 1);
            $updated = true;
          } else if ((isset($_REQUEST) || isset($_POST)) && get_option('json_api_benchmarking') != 0) {
            $this->save_option('json_api_benchmarking', 0);
            $updated = true;
          }
    
          // Update notification
          if ($updated) {
            ?><div class="updated">Settings have been updated.</div><?php
          }
    
          // Database validity checks
          if (!preg_match('_^[0-9]+$_', get_option( 'json_api_cache_duration'))) {
            $this->save_option('json_api_cache_duration', 0);
            ?><div class="error">Caching time value in database contained invalid characters and has been reset to 0.</div><?php
          }

    and finally change line 219 from

    <?php } ?>

    to

    <?php } ?>
        <h3>Global caching</h3>
        <p>JSON API can remember all requests it has received and the corresponding responses sent for a specified amount of time. If an identical comes in during that time, the remembered response is sent, avoiding having to fully process the request. This provides a speed boost when serving multiple similar requests within short periods of time, but can also cause issues by sending outdated responses.</p>
        <p>Should not be used if any of the methods of any of the controllers enabled above allow modifying the database.</p>
        <table class="form-table">
          <tr valign="top">
            <th scope="row">Caching time</th>
            <td><input type="text" name="json_api_cache_duration" value="<?php echo get_option('json_api_cache_duration', 0); ?>" size="4" /> seconds</td>
          </tr>
        </table>
        <h3>Benchmarking</h3>
        <p>When benchmarking is enabled, the time spent is displayed in the end of every JSON response. Only for testing purposes.</p>
        <table class="form-table">
          <tr valign="top">
            <th scope="row">Enable benchmarking</th>
            <td><input type="checkbox" name="json_api_benchmarking" <?php echo ( get_option('json_api_benchmarking') ? 'checked="checked" ' : '' ); ?>/></td>
          </tr>
        </table>

    https://www.ads-software.com/plugins/json-api/

  • The topic ‘[PATCH] Adding caching, benchmarking, and setting change notices’ is closed to new replies.