{"id":12,"date":"2008-12-10T15:50:25","date_gmt":"2008-12-10T20:50:25","guid":{"rendered":"http:\/\/www.danielansari.com\/wordpress\/?p=12"},"modified":"2016-10-10T12:31:24","modified_gmt":"2016-10-10T17:31:24","slug":"how-to-use-the-rest-api-in-elgg-11","status":"publish","type":"post","link":"http:\/\/www.danielansari.com\/wordpress\/2008\/12\/how-to-use-the-rest-api-in-elgg-11\/","title":{"rendered":"How to use the REST API in Elgg 1.1"},"content":{"rendered":"<p>The <a href=\"http:\/\/www.elgg.org\/\">Elgg<\/a> documentation <a href=\"http:\/\/community.elgg.org\/pg\/pages\/view\/70\/\">describes the REST API<\/a> rather superficially, yet provides no samples, and is now inaccurate for the recent versions of Elgg.<\/p>\n<p>After a minor modification to your .htaccess file, using the REST API is very simple, and, in many cases, avoids the need to create individual files in your Elgg root directory to provide custom functionality.<\/p>\n<p>First, let&#8217;s look at how your API method would be called:<\/p>\n<p><code>http:\/\/localhost:8080\/elgg\/pg\/api\/rest?method=login&amp;username=dansari&amp;password=apples<\/code><\/p>\n<p>Let me explain technically what&#8217;s going on first. Any API calls in Elgg are handled by a <em>page handler,<\/em> <em>i.e.,<\/em> when the HTTP request begins with <code>\/pg\/...<\/code>, the .htaccess (containing <code>mod_rewrite<\/code> rules) tells Apache to use the Elgg file <code>engine\/handlers\/pagehandler.php<\/code> to handle the request. Elgg then determines which page handler to use, and invokes it. The REST API is known as an &#8220;API endpoint&#8221;. In this case, because the next part of the URL is <code>rest<\/code>, the API page handler passes control to the file <code>services\/api\/rest.php<\/code>.<\/p>\n<p>The problem with the .htaccess that ships with Elgg is that it would cause the page handler to be invoked as <code>pagehandler.php?handler=api&amp;page=rest<\/code>, discarding the querystring entirely. <code>services\/api\/rest.php<\/code> actually expects the method parameters to be in the querystring, so to get this to work, we simply change the following line in .htaccess:<\/p>\n<pre>RewriteRule ^pg\\\/([A-Za-z\\_\\-]+)\\\/(.*)$\r\nengine\/handlers\/pagehandler.php?handler=$1&amp;page=$2<\/pre>\n<p>to this:<\/p>\n<pre>RewriteRule ^pg\\\/([A-Za-z\\_\\-]+)\\\/(.*)$\r\nengine\/handlers\/pagehandler.php?handler=$1&amp;page=$2 [QSA]<\/pre>\n<p>Here is the code for a sample REST method, which would be implemented via a plugin. For this example, the following file is located at <code>mod\/rest_login\/start.php<\/code> (<em>NB<\/em> I had to put a space character before the <code>?php<\/code> in line 1 for WordPress to render this listing):<\/p>\n<link rel=\"stylesheet\" href=\"http:\/\/www.danielansari.com\/wordpress\/wp-content\/plugins\/codeviewer\/codeviewer.css\" type=\"text\/css\" media=\"all\" \/>\n<ol class=\"codelist\">\n<li value=\"1\" class=\"tab0 odd\"><code><span style=\"color: #339933;\">&lt;<\/span> ?php<\/code><\/li>\n<li value=\"2\" class=\"even\">&nbsp;<\/li>\n<li value=\"3\" class=\"tab1 odd\"><code><span style=\"color: #000000; font-weight: bold;\">function<\/span> rest_login_init<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span><\/code><\/li>\n<li value=\"4\" class=\"tab2 even\"><code>expose_function<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000ff;\">'login'<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #0000ff;\">'rest_login_handler'<\/span><span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a><span style=\"color: #009900;\">&#40;<\/span><\/code><\/li>\n<li value=\"5\" class=\"tab6 odd\"><code><span style=\"color: #0000ff;\">&quot;username&quot;<\/span> <span style=\"color: #339933;\">=&gt;<\/span> <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000ff;\">&quot;type&quot;<\/span> <span style=\"color: #339933;\">=&gt;<\/span> <span style=\"color: #0000ff;\">&quot;string&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">,<\/span><\/code><\/li>\n<li value=\"6\" class=\"tab6 even\"><code><span style=\"color: #0000ff;\">&quot;password&quot;<\/span> <span style=\"color: #339933;\">=&gt;<\/span> <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000ff;\">&quot;type&quot;<\/span> <span style=\"color: #339933;\">=&gt;<\/span> <span style=\"color: #0000ff;\">&quot;string&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><\/code><\/li>\n<li value=\"7\" class=\"tab6 odd\"><code><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #0000ff;\">&quot;&quot;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #0000ff;\">&quot;GET&quot;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000000; font-weight: bold;\">false<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000000; font-weight: bold;\">true<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/code><\/li>\n<li value=\"8\" class=\"tab1 even\"><code><span style=\"color: #009900;\">&#125;<\/span><\/code><\/li>\n<li value=\"9\" class=\"odd\">&nbsp;<\/li>\n<li value=\"10\" class=\"tab1 even\"><code><span style=\"color: #000000; font-weight: bold;\">function<\/span> rest_login_handler<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$username<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$password<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span><\/code><\/li>\n<li value=\"11\" class=\"tab2 odd\"><code><span style=\"color: #000088;\">$persistent<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #0000ff;\">&quot;1&quot;<\/span><span style=\"color: #339933;\">;<\/span><\/code><\/li>\n<li value=\"12\" class=\"tab2 even\"><code><span style=\"color: #000088;\">$result<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000000; font-weight: bold;\">false<\/span><span style=\"color: #339933;\">;<\/span><\/code><\/li>\n<li value=\"13\" class=\"tab2 odd\"><code><span style=\"color: #b1b100;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #339933;\">!<\/span><a href=\"http:\/\/www.php.net\/empty\"><span style=\"color: #990000;\">empty<\/span><\/a><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$username<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #339933;\">&amp;&amp;<\/span> <span style=\"color: #339933;\">!<\/span><a href=\"http:\/\/www.php.net\/empty\"><span style=\"color: #990000;\">empty<\/span><\/a><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$password<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span><\/code><\/li>\n<li value=\"14\" class=\"tab3 even\"><code><span style=\"color: #b1b100;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$user<\/span> <span style=\"color: #339933;\">=<\/span> authenticate<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$username<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #000088;\">$password<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span><\/code><\/li>\n<li value=\"15\" class=\"tab4 odd\"><code><span style=\"color: #000088;\">$result<\/span> <span style=\"color: #339933;\">=<\/span> login<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$user<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$persistent<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/code><\/li>\n<li value=\"16\" class=\"tab3 even\"><code><span style=\"color: #009900;\">&#125;<\/span><\/code><\/li>\n<li value=\"17\" class=\"tab2 odd\"><code><span style=\"color: #009900;\">&#125;<\/span><\/code><\/li>\n<li value=\"18\" class=\"tab2 even\"><code><span style=\"color: #b1b100;\">return<\/span> <span style=\"color: #000088;\">$result<\/span><span style=\"color: #339933;\">;<\/span><\/code><\/li>\n<li value=\"19\" class=\"tab1 odd\"><code><span style=\"color: #009900;\">&#125;<\/span><\/code><\/li>\n<li value=\"20\" class=\"even\">&nbsp;<\/li>\n<li value=\"21\" class=\"tab1 odd\"><code><span style=\"color: #666666; font-style: italic;\">\/\/ Add the plugin's init function to the system's init event<\/span><\/code><\/li>\n<li value=\"22\" class=\"tab1 even\"><code>register_elgg_event_handler<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000ff;\">'init'<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'system'<\/span><span style=\"color: #339933;\">,<\/span><span style=\"color: #0000ff;\">'rest_login_init'<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/code><\/li>\n<li value=\"23\" class=\"odd\">&nbsp;<\/li>\n<li value=\"24\" class=\"tab0 even\"><code><span style=\"color: #000000; font-weight: bold;\">?&gt;<\/span><\/code><\/li>\n<\/ol>\n<p>The important differences between what is stated in the Elgg documentation and here are:<\/p>\n<ul>\n<li>There is no <code>register_method<\/code> function. Instead, use <code>expose_function<\/code> as in line 4.<\/li>\n<li><code>\"type\"<\/code> must be specified for each parameter, as in lines 5-6.<\/li>\n<\/ul>\n<p>Finally, here is an excerpt from <code>engine\/lib\/api.php<\/code>, which explains the parameters in more detail:<\/p>\n<link rel=\"stylesheet\" href=\"http:\/\/www.danielansari.com\/wordpress\/wp-content\/plugins\/codeviewer\/codeviewer.css\" type=\"text\/css\" media=\"all\" \/>\n<ol class=\"codelist\">\n<li value=\"364\" class=\"tab1 even\"><code><span style=\"color: #666666; font-style: italic;\">\/**<\/span><\/code><\/li>\n<li value=\"365\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> Expose an arbitrary <span style=\"color: #000000; font-weight: bold;\">function<\/span> <span style=\"color: #b1b100;\">as<\/span> an api call<span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"366\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span><\/code><\/li>\n<li value=\"367\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> Limitations<span style=\"color: #339933;\">:<\/span> Currently can not expose functions which expect objects<span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"368\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span><\/code><\/li>\n<li value=\"369\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param string <span style=\"color: #000088;\">$method<\/span> The api name to expose this <span style=\"color: #b1b100;\">as<\/span><span style=\"color: #339933;\">,<\/span> eg <span style=\"color: #0000ff;\">&quot;myapi.dosomething&quot;<\/span><\/code><\/li>\n<li value=\"370\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param string <span style=\"color: #000088;\">$function<\/span> Your <span style=\"color: #000000; font-weight: bold;\">function<\/span> callback<span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"371\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a> <span style=\"color: #000088;\">$parameters<\/span> Optional <a href=\"http:\/\/www.php.net\/list\"><span style=\"color: #990000;\">list<\/span><\/a> of parameters in the same order <span style=\"color: #b1b100;\">as<\/span> in your <span style=\"color: #000000; font-weight: bold;\">function<\/span><span style=\"color: #339933;\">,<\/span> with optional parameters last<span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"372\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span> &nbsp; &nbsp; &nbsp; This <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a> should be in the format<\/code><\/li>\n<li value=\"373\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> &nbsp; <span style=\"color: #0000ff;\">&quot;variable&quot;<\/span> <span style=\"color: #339933;\">=<\/span> <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a> <span style=\"color: #009900;\">&#40;<\/span><\/code><\/li>\n<li value=\"374\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type <span style=\"color: #339933;\">=&gt;<\/span> <span style=\"color: #0000ff;\">'int'<\/span> <span style=\"color: #339933;\">|<\/span> <span style=\"color: #0000ff;\">'bool'<\/span> <span style=\"color: #339933;\">|<\/span> <span style=\"color: #0000ff;\">'float'<\/span> <span style=\"color: #339933;\">|<\/span> <span style=\"color: #0000ff;\">'string'<\/span> <span style=\"color: #339933;\">|<\/span> <span style=\"color: #0000ff;\">'array'<\/span><\/code><\/li>\n<li value=\"375\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; required <span style=\"color: #339933;\">=&gt;<\/span> <span style=\"color: #000000; font-weight: bold;\">true<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000000; font-weight: bold;\">default<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #339933;\">|<\/span> <span style=\"color: #000000; font-weight: bold;\">false<\/span><\/code><\/li>\n<li value=\"376\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span> &nbsp; &nbsp; &nbsp; &nbsp;<span style=\"color: #009900;\">&#41;<\/span><\/code><\/li>\n<li value=\"377\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param string <span style=\"color: #000088;\">$description<\/span> Optional human readable description of the <span style=\"color: #000000; font-weight: bold;\">function<\/span><span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"378\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param string <span style=\"color: #000088;\">$call_method<\/span> <a href=\"http:\/\/www.php.net\/define\"><span style=\"color: #990000;\">Define<\/span><\/a> what call method should be used <span style=\"color: #b1b100;\">for<\/span> this <span style=\"color: #000000; font-weight: bold;\">function<\/span><span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"379\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param bool <span style=\"color: #000088;\">$require_auth_token<\/span> Whether this requires a user authentication token or not <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000000; font-weight: bold;\">default<\/span> is <span style=\"color: #000000; font-weight: bold;\">true<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"380\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span>param bool <span style=\"color: #000088;\">$anonymous<\/span> Can anonymous <span style=\"color: #009900;\">&#40;<\/span>non<span style=\"color: #339933;\">-<\/span>authenticated in any way<span style=\"color: #009900;\">&#41;<\/span> users execute this call<span style=\"color: #339933;\">.<\/span><\/code><\/li>\n<li value=\"381\" class=\"tab2 odd\"><code><span style=\"color: #339933;\">*<\/span> <span style=\"color: #339933;\">@<\/span><span style=\"color: #b1b100;\">return<\/span> bool<\/code><\/li>\n<li value=\"382\" class=\"tab2 even\"><code><span style=\"color: #339933;\">*\/<\/span><\/code><\/li>\n<li value=\"383\" class=\"tab1 odd\"><code><span style=\"color: #000000; font-weight: bold;\">function<\/span> expose_function<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000088;\">$method<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$function<\/span><span style=\"color: #339933;\">,<\/span> <a href=\"http:\/\/www.php.net\/array\"><span style=\"color: #990000;\">array<\/span><\/a> <span style=\"color: #000088;\">$parameters<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000000; font-weight: bold;\">NULL<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$description<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #0000ff;\">&quot;&quot;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$call_method<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #0000ff;\">&quot;GET&quot;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$require_auth_token<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000000; font-weight: bold;\">true<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #000088;\">$anonymous<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000000; font-weight: bold;\">false<\/span><span style=\"color: #009900;\">&#41;<\/span><\/code><\/li>\n<\/ol>\n<p>There are limitations of the REST API, one of them being that the return value is rendered in a view. You can override the view by including the directory structure and file <code>views\/default\/api\/output.php<\/code> in your module directory, but Elgg will still render it as HTML; if you need to process the result, you will need to parse this HTML. Also, if you decide to override this view, it will be overridden for any REST API method calls, not just the one implemented in your module.<\/p>\n<p>One particular limitation of the sample above is that it does not authenticate! At least I couldn&#8217;t get it to work; the reason is that the API method is registered as not requiring a user authentication token. As a result, the method executes in unauthenticated fashion, and when <code>authenticate()<\/code> is called to attempt to authenticate the user, it always succeeds &#8211; regardless of the password &#8211; because <code>pam_authenticate()<\/code> returns true for the executing method. (Hopefully this would make sense to you if you&#8217;ve written an authentication plugin.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Elgg documentation describes the REST API rather superficially, yet provides no samples, and is now inaccurate for the recent versions of Elgg. After a minor modification to your .htaccess file, using the REST API is very simple, and, in many cases, avoids the need to create individual files in your Elgg root directory to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[8,3,7],"_links":{"self":[{"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/posts\/12"}],"collection":[{"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":37,"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":108,"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/posts\/12\/revisions\/108"}],"wp:attachment":[{"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/media?parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/categories?post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.danielansari.com\/wordpress\/wp-json\/wp\/v2\/tags?post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}