Slide 1

Slide 1 text

The WordPress REST API Ryan McCue
 Senior Engineer at Human Made

Slide 2

Slide 2 text

What API?

Slide 3

Slide 3 text

What API? XML-RPC API

Slide 4

Slide 4 text

What API? Modern REST APIs

Slide 5

Slide 5 text

What API? Modern REST APIs

Slide 6

Slide 6 text

Modern REST APIs What API?

Slide 7

Slide 7 text

Modern REST APIs What API?

Slide 8

Slide 8 text

What API? WordPress REST API

Slide 9

Slide 9 text

What API? Lead Developers Ryan McCue Rachel Baker

Slide 10

Slide 10 text

What API? Contributing Developers Daniel Bachhuber Joe Hoyle 53 total contributors

Slide 11

Slide 11 text

What API? Version 2

Slide 12

Slide 12 text

How do I use it?

Slide 13

Slide 13 text

Using the API Install the Plugin Version 1: Plugins > Beta Testing > JSON REST API Version 2: github.com/WP-API/WP-API

Slide 14

Slide 14 text

Using the API What is REST?

Slide 15

Slide 15 text

What is REST? Using the API GET Get the resource POST Create a new resource PUT Update a resource DELETE Delete a resource

Slide 16

Slide 16 text

Single Post Using the API GET /wp/v2/posts/42 Get post 42 PUT /wp/v2/posts/42 Update post 42 DELETE /wp/v2/posts/42 Delete (trash) post 42

Slide 17

Slide 17 text

Posts Using the API GET /wp/v2/posts Get the latest posts POST /wp/v2/posts Create a new post

Slide 18

Slide 18 text

Using the API Posts ✔ Pages ✔ Media ✔ Custom Post Types ✔ Post Meta ✔ Revisions ✔ Comments ✔ Terms ✔ Users ✔

Slide 19

Slide 19 text

Using the API Discovery

Slide 20

Slide 20 text

Using the API Discovery ==> HEAD http://www.wired.com/ <== HTTP/1.1 200 OK
 <== Link: ;
 rel="http://github.com/WP-API/WP-API"

Slide 21

Slide 21 text

Using the API Authentication

Slide 22

Slide 22 text

Authentication Using the API Cookie Authentication

Slide 23

Slide 23 text

Authentication Using the API OAuth 1.0a

Slide 24

Slide 24 text

Using the API Try it out!

Slide 25

Slide 25 text

Try it out! Using the API brisbane.wordcamp.org/2015/wp-json/ www.wired.com/wp-json/ poststatus.com/wp-json/

Slide 26

Slide 26 text

How do I extend it?

Slide 27

Slide 27 text

Extending Don’t Hack Core

Slide 28

Slide 28 text

Extending /** * Grab latest post title by an author! * * @param array $data Options for the function. * @return string|null Post title for the latest,
 * or null if none. */ function my_awesome_func( $data ) { $posts = get_posts( array( 'author' => $data['id'], ) ); if ( empty( $posts ) ) { return null; } return $posts[0]->post_title; }

Slide 29

Slide 29 text

Extending add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P\d+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', ) ); } );

Slide 30

Slide 30 text

Extending $ http api.local/wp-json/myplugin/v1/author/1 HTTP/1.1 200 OK Allow: GET "Hello!"

Slide 31

Slide 31 text

Extending $ http api.local/wp-json/myplugin/v1/author/999 HTTP/1.1 200 OK Allow: GET null

Slide 32

Slide 32 text

Extending /** * Grab latest post title by an author! * * @param array $data Options for the function. * @return string|null Post title for the latest,
 * or null if none. */ function my_awesome_func( $data ) { $posts = get_posts( array( 'author' => $data['id'], ) ); if ( empty( $posts ) ) { return null; } return $posts[0]->post_title; }

Slide 33

Slide 33 text

Extending /** * Grab latest post title by an author! * * @param array $data Options for the function. * @return string|null Post title for the latest,
 * or null if none. */ function my_awesome_func( $data ) { $posts = get_posts( array( 'author' => $data['id'], ) ); if ( empty( $posts ) ) { return new WP_Error( 'no_author', 'Invalid author',
 array( 'status' => 404 ) ); } return $posts[0]->post_title; }

Slide 34

Slide 34 text

Extending $ http api.local/wp-json/myplugin/v1/author/999 HTTP/1.1 200 OK Allow: GET null

Slide 35

Slide 35 text

Extending $ http api.local/wp-json/myplugin/v1/author/999 HTTP/1.1 404 Not Found Allow: GET [{ "code": "no_author", "message": "Invalid author", "data": { "status": 404 } }]

Slide 36

Slide 36 text

Extending Namespaces register_rest_route( 'myplugin/v1', '…', array(…) );

Slide 37

Slide 37 text

Extending $ http api.local/wp-json/ HTTP/1.1 200 OK Allow: GET { … "namespaces": [ "wp/v2", "myplugin/v1" ] }

Slide 38

Slide 38 text

Extending /** * Grab latest post title by an author! * * @param array $data Options for the function. * @return string|null Post title for the latest,
 * or null if none. */ function my_awesome_func( $data ) { $posts = get_posts( array( 'author' => $data['id'], ) ); if ( empty( $posts ) ) { return new WP_Error( 'no_author', 'Invalid author',
 array( 'status' => 404 ) ); } return $posts[0]->post_title; }

Slide 39

Slide 39 text

Extending add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P\d+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', ) ); } );

Slide 40

Slide 40 text

Extending add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P\d+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', 'args' => array( 'id' => array( 'sanitize_callback' => 'absint', ), ), ) ); } );

Slide 41

Slide 41 text

Extending add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P.+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', 'args' => array( 'id' => array( 'validate_callback' => function ( $val ) { return is_numeric( $val ); }, ), ), ) ); } );

Slide 42

Slide 42 text

Extending $ http api.local/wp-json/myplugin/v1/author/foo HTTP/1.1 400 Bad Request Allow: GET [{ "code": "rest_invalid_param", "message": "Invalid parameter(s): Invalid param.", "data": { "status": 400, "params": { "id": "Invalid param." } } }]

Slide 43

Slide 43 text

Extending add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P.+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', 'args' => array( 'id' => array( 'validate_callback' => function ( $val ) { return is_numeric( $val ); }, ), ), ) ); } );

Slide 44

Slide 44 text

Extending add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P.+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', 'args' => array( 'id' => array( 'validate_callback' => function ( $val ) { return is_numeric( $val ); }, ), ), 'permission_callback' => function () { return current_user_can( 'manage_options' ); } ) ); } );

Slide 45

Slide 45 text

Extending $ http api.local/wp-json/myplugin/v1/author/4 HTTP/1.1 403 Forbidden Allow: GET [{ "code": "rest_forbidden", "message": "You don't have permission to do this.", "data": { "status": 403 } }]

Slide 46

Slide 46 text

gist.github.com/rmccue
 v2.wp-api.org poststatus.com/wordpress-json-rest-api/

Slide 47

Slide 47 text

Thanks. @rmccue
 rmccue.io