Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

API discovery ala RSD #40

Merged
merged 1 commit into from

3 participants

Max Cutler Ryan McCue Marin Marušić
Max Cutler
Collaborator

As a developer of API clients, I'd really love a proper API discovery mechanism for WP-API. The XML-RPC API uses RSD, which allows clients to do an algorithm like:

  1. Ask user for their blog URL
  2. GET that URL and find the <link rel="EditURI" .../> tag.
  3. Extract the href from that <link> and GET it.
  4. Parse the RSD file to determine which endpoints are supported and preferred.

Of course, sometimes overzealous theme authors will strip this default <link> tag and we have to fallback to blindly checking /xmlrpc.php?rsd, but fortunately that's not too common.

My recommendation is that WP-API do (at least) one of the following:

  1. Add itself to the existing RSD file. This makes it easy for existing XML-RPC clients to "upgrade" to the JSON API when available, though it still means dealing with XML which is a pain.
  2. Add a new <link> tag to the blog <head> that clients can look for.
  3. Send a new HTTP header on WP page responses with the path to the API
  4. ???

Blindly searching for /wp-json.php or some rewrite-rule variant should really be avoided if at all possible.

Max Cutler
Collaborator

Another motivation is to avoid issues like WP#18731, where you can't rename xmlrpc.php file without breaking compatibility with the world. If WP-API ships in core with a robust discovery mechanism then that allows for more flexibility for atypical deployment patterns or pretty URLs or whatever.

Ryan McCue
Owner

:+1:

I'd like to do this two-fold:

  1. Add it to the RSD, as noted
  2. Send via a Link header on all pages (including frontend and backend)

The latter should be the preferred option, since it's then a single HEAD request to find the API.

Marin Marušić

why not JSON-LD ? It's pretty new granted, but if you go down the JSON path, why not go the whole way?
or Swagger ? https://github.com/wordnik/swagger-core/wiki ... For me the more important question in today's web is what can an API do for me... Swagger displays that beautifully

I look at wordpress more and more as an application development platform, IMHO it should go along with the times... Using XML to describe JSON is illogical ...

Ryan McCue
Owner

Using XML to describe JSON is illogical ...

In this case, it's because RSD is a known quantity and it already has parsers. Creating our own standard is more illogical, really.

That said, this is just for discovering the API, nothing else. We use JSON Schema to describe the output of the API already.

Ryan McCue rmccue merged commit ff7fa5a into from
Ryan McCue rmccue deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 17, 2013
  1. Ryan McCue
This page is out of date. Refresh to see the latest.
Showing with 39 additions and 0 deletions.
  1. +39 −0 plugin.php
39 plugin.php
View
@@ -143,6 +143,45 @@ function json_register_scripts() {
add_action( 'wp_enqueue_scripts', 'json_register_scripts', -100 );
/**
+ * Add the API URL to the WP RSD endpoint
+ */
+function json_output_rsd() {
+?>
+ <api name="WP-API" blogID="1" preferred="false" apiLink="<?php echo get_json_url() ?>" />
+<?php
+}
+add_action( 'xmlrpc_rsd_apis', 'json_output_rsd' );
+
+/**
+ * Output API link tag into page header
+ */
+function json_output_link_wp_head() {
+ $api_root = get_json_url();
+
+ if ( empty( $api_root ) )
+ return;
+
+ echo "<link rel='https://github.com/WP-API/WP-API' href='" . esc_url( $api_root ) . "' />\n";
+}
+add_action( 'wp_head', 'json_output_link_wp_head', 10, 0 );
+
+/**
+ * Send a Link header for the API
+ */
+function json_output_link_header() {
+ if ( headers_sent() )
+ return;
+
+ $api_root = get_json_url();
+
+ if ( empty($api_root) )
+ return;
+
+ header('Link: <' . $api_root . '>; rel="https://github.com/WP-API/WP-API"', false);
+}
+add_action( 'template_redirect', 'json_output_link_header', 11, 0 );
+
+/**
* Get URL to a JSON endpoint on a site
*
* @todo Check if this is even necessary
Something went wrong with that request. Please try again.