WordPress REST API

Get the latest posts with the REST API

Description: Call the REST API of your site and get the two newest posts. Show only the fields id, slug and title.

Hint:

  • The route is /wp-json/wp/v2/posts. Use per_page and _fields.

Solution

Terminal output

$ curl -s "http://example.com/wp-json/wp/v2/posts?per_page=2&_fields=id,slug,title" | jq -c '.[]'
{"id":7,"slug":"post-three","title":{"rendered":"Post three"}}
{"id":6,"slug":"post-two","title":{"rendered":"Post two"}}

How it works

  • The posts come newest first, and per_page=2 limits the result.
  • _fields keeps the response small, the title is an object with a rendered key.

Read REST API Posts.

Create a post with the REST API and an application password

Description: Create an application password and use it to add a draft post Posted by API through the REST API. Show the ID and the status of the new post.

Hint:

  • Use Basic authentication: curl -u user:application-password.
  • The method for creating is POST on /wp-json/wp/v2/posts.

Solution

Terminal output

$ curl -s -u "admin:APP_PASSWORD" -X POST "http://example.com/wp-json/wp/v2/posts" -H "Content-Type: application/json" -d '{"title":"Posted by API","status":"draft"}' | jq -c '{id, status, type}'
{"id":5,"status":"draft","type":"post"}
$ curl -s -X POST "http://example.com/wp-json/wp/v2/posts" -d "title=No login" | jq -c '{code, status: .data.status}'
{"code":"rest_cannot_create","status":401}

How it works

  • The application password proves who you are, so WordPress accepts the request (code 201 and the new post).
  • Without the login, the same request is refused with the status 401.

Read REST API Authentication.

Build a custom REST endpoint which greets a name

Description: Create the endpoint GET /wp-json/tc/v1/greet?name=Riya, which returns {"greeting":"Hello, Riya!"}. If the name has more than 20 characters, the endpoint must return an error with the status 400.

Hint:

  • Use register_rest_route() with a validate_callback for the name argument.
  • A route needs a permission_callback.

Solution

<?php
add_action( 'rest_api_init', function () {
	register_rest_route( 'tc/v1', '/greet', array(
		'methods'             => 'GET',
		'permission_callback' => '__return_true',
		'args'                => array(
			'name' => array(
				'required'          => true,
				'validate_callback' => function ( $value ) {
					return is_string( $value ) && strlen( $value ) <= 20;
				},
				'sanitize_callback' => 'sanitize_text_field',
			),
		),
		'callback'            => function ( WP_REST_Request $request ) {
			return array( 'greeting' => 'Hello, ' . $request['name'] . '!' );
		},
	) );
} );
Terminal output

$ curl -s "http://example.com/wp-json/tc/v1/greet?name=Riya"
{"greeting":"Hello, Riya!"}
$ curl -s "http://example.com/wp-json/tc/v1/greet?name=ThisNameIsMuchTooLongForUs" | jq -c '{code, status: .data.status}'
{"code":"rest_invalid_param","status":400}
$ curl -s "http://example.com/wp-json/tc/v1/greet" | jq -c '{code, message}'
{"code":"rest_missing_callback_param","message":"Missing parameter(s): name"}

How it works

  • The route is on the rest_api_init hook. WordPress checks the arguments before the callback runs.
  • A failed validate_callback gives rest_invalid_param with the status 400, and a missing required argument gives an error too.

Read Custom REST Endpoint.