Slide 1

Slide 1 text

APIness

Slide 2

Slide 2 text

NOPE

Slide 3

Slide 3 text

APIs in WordPress ➔ Dashboard Widgets API ➔ Database API ➔ HTTP API ➔ File Header API ➔ Filesystem API ➔ Metadata API ➔ Options API ➔ Plugin API ➔ Quicktags API ➔ Rewrite API ➔ Settings API ➔ Shortcode API ➔ Theme Modification API ➔ Theme Customization API ➔ Transients API ➔ Widgets API ➔ XML-RPC WordPress API

Slide 4

Slide 4 text

douglas adams “the fundamental interconnectedness of all things”

Slide 5

Slide 5 text

douglas adams “the fundamental interconnectedness of all things”

Slide 6

Slide 6 text

data in / data out / events

Slide 7

Slide 7 text

RSS

Slide 8

Slide 8 text

$feed = fetch_feed( $uri ); // feed cache defaults to 12 hours add_filter( 'wp_feed_cache_transient_lifetime', function( $seconds ) { return 60*60; // 1 hour } );

Slide 9

Slide 9 text

oEmbed

Slide 10

Slide 10 text

2 ways to extend oEmbed: // For sites that have an oEmbed endpoint wp_oembed_add_provider( $format, $provider, $regex ); // For everything else wp_embed_register_handler( $id, $regex, $callback, $priority ); function custom_embed( $matches, $attr, $url, $rawattr ) { // scrape target page, implement iframe embed etc... }

Slide 11

Slide 11 text

Register handler for github gists: wp_embed_register_handler( ‘github-gists’, ‘#^(https?://gist.github.com/[^/]+/.+)$#i’, ‘github_embed’ ); function github_embed( $matches, $attr, $url, $rawattr ) { return ‘’; }

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

what about something more custom? using the HTTP API in WordPress

Slide 14

Slide 14 text

making requests

Slide 15

Slide 15 text

wp_remote_* // Performs a GET request wp_remote_get( $url, $args ); // POST request wp_remote_post( $url, $args );

Slide 16

Slide 16 text

wp_remote_* // use $args[ ‘body’ ] to POST // variables to $url wp_remote_get( $url, array( ‘body’ => array( ‘parameter’ => $value ) ) );

Slide 17

Slide 17 text

// Fetch new auth keys for wp-config.php $url = ‘https://api.wordpress.org/secret-key/1.1/salt/’; $result = wp_remote_get( $url ); $keys = false; if ( ! is_wp_error( $result ) ) { // response contains information about the request if ( $result[ ‘response’ ][ ‘code’ ] === 200 ) $keys = $result[ ‘body’ ]; } // do something with $keys ¯\(°_o)/¯

Slide 18

Slide 18 text

// Convert some markdown to HTML using Github $url = ‘https://api.github.com/markdown’; $result = wp_remote_post( $url, array( ‘body’ => array( ‘text’ => ‘# Air Hair Lair! #’ ) ) ); echo $result[ ‘body’ ]; //

Air Hair Lair!

Slide 19

Slide 19 text

performance wait right there, just nipping out for some milk

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

caching obvs

Slide 22

Slide 22 text

using options persistent

Slide 23

Slide 23 text

$text = $_POST[ ‘markdown’ ]; $option_key = ‘markdown_’ . md5( $text ); // Check if we have the conversion already // using a hash as the key if ( false === ( $markdown = get_option( $option_key ) ) ) { $result = wp_remote_post( $url, ... ); $markdown = $result[ ‘body’ ]; update_option( $option_key, $markdown ); } echo $markdown;

Slide 24

Slide 24 text

using transients expiring caches

Slide 25

Slide 25 text

$text = $_POST[ ‘markdown’ ]; $transient_key = ‘markdown_’ . md5( $text ); // Check if we have the conversion already // using a hash as the key if ( false === ( $rsp = get_transient( $transient_key ) ) ) { $result = wp_remote_post( $url, ... ); $rsp = $result[ ‘body’ ]; set_transient( $transient_key, $rsp, 60*60 ); // 1 hour } echo $rsp;

Slide 26

Slide 26 text

delayed gratification making requests in the background

Slide 27

Slide 27 text

wp_schedule_event() wp_schedule_event( $timestamp, $recurrence, $hook, $args ); Instead of making the API call immediately, defer it.

Slide 28

Slide 28 text

wp_schedule_single_event() wp_schedule_single_event( $timestamp, $hook, $args ); Adds an event that will only run once after $timestamp has passed

Slide 29

Slide 29 text

add_action( ‘trigger_api’, ‘do_api_call’, 10, 2 ); function do_api_call( $url, $args ) { // fetch / send data & cache response } function api_call( $url, $args ) { $key = md5( $url . serialize( $args ) ); if ( false === ( $data = get_transient( $key ) ) ) { wp_schedule_single_event( time(), ‘trigger_api’, array( ‘url’ => $url, ‘args’ => $args ) ); } return $data; }

Slide 30

Slide 30 text

TLC Transients https://github.com/markjaquith/WP-TLC-Transients

Slide 31

Slide 31 text

witness the fitness echo tlc_transient( 'example-feed' ) ->updates_with( 'my_callback', $args ) ->expires_in( 300 ) ->background_only() ->get();

Slide 32

Slide 32 text

rate limiting the accidental DOS attack

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

headers are useful $result = wp_remote_post( $url ); // number of requests per rate limit window $result[ ‘headers’ ][ ‘X-Rate-Limit-Limit’ ]; // number of requests you have left $result[ ‘headers’ ][ ‘X-Rate-Limit-Remaining’ ]; // the unix time when the limit remaining resets $result[ ‘headers’ ][ ‘X-Rate-Limit-Reset’ ];

Slide 35

Slide 35 text

$limits = get_option( ‘ratelimit_’ . md5( $url ) ); if ( false === ( $data = get_option( $key ) ) && $limits && $limits[‘remaining’] > 0 ) { $result = wp_remote_post( $url ); $limits = array( ‘remaining’ => $result[‘headers’][‘X-Rate-Limit-Remaining’], ‘reset’ => $result[‘headers’][‘X-Rate-Limit-Reset’] ); update_option( ‘ratelimit_’ . md5( $url ), $limits ); update_option( $key, $result[ ‘body’ ] ); }

Slide 36

Slide 36 text

OAuth because security

Slide 37

Slide 37 text

tmhOAuth https://github.com/themattharris/tmhOAuth

Slide 38

Slide 38 text

tmhOAuth $api = new tmhOAuth( array( ‘host’ => ‘api.twitter.com’ 'consumer_key' => '', 'consumer_secret' => '', 'token' => '', 'secret' => '', ) ); $data = $api->request( ‘POST’, $url, $params );

Slide 39

Slide 39 text

WordPress as an API

Slide 40

Slide 40 text

Jetpack JSON API requires wordpress.com

Slide 41

Slide 41 text

JSON API http://wordpress.org/plugins/json-api/

Slide 42

Slide 42 text

WP-API https://github.com/WP-API/WP-API

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

in practice // you can make requests to URLs like the following /wp-json/posts/ // the above supports the following methods: // "HEAD", // "GET", returns an entity // "POST", adds a new entity // "PUT", updates an entity // "DELETE" deletes the entity

Slide 45

Slide 45 text

Thanks for listening @sanchothefat