Phil Sturgeon

Web developer, kayaker, outdoors madman and part-time alcoholic.


REST implementation for CodeIgniter

Posted CodeIgniter at Jun 03, 2009

I have seen 1 or 2 RESTful implementations for CodeIgniter but the syntax and methodology for each of them left me feeling like it could be done better.

Firstly, REST is not something that can be put into a library. It is not a "thing" and cannot be treated as such.

Secondly, REST calls should not be mixed in with your normal controllers. It should be kept separate from your normal controllers as they are not the same. The default behavior should be slightly different as REST calls are not simple GET -> output.

Thirdly, REST controllers need to remain flexible. For that reason the normal CodeIgniter URI segments are not enough. To keep the controllers flexible, associative URI segments should be enforced so any combination of parameters can be used.

Finally, REST controllers should be able to output the response in many number of formats. These formats should be specified by the requester and not set in stone within the code. This means a REST controller needs to detect the desired format in two different ways.

It took a great deal more thought and consideration than it did actual implementation. Here is the code I have used to get my CodeIgniter RESTful implementation working, tested and complete.

application/libraries/REST_Controller.php - This new controller type will contain all of the logic for our new REST controllers.

application/config/rest.php - Control login restrictions and caching for your REST server.

application/controllers/example_api.php - This is an example of a REST controller with some basic user data. This can be called anything you like and be placed in Matchbox modules, sub-directories, whatever.

Useage

Now it is all set up and ready go. Crack open your browser and try URL's in these formats to see what happens:

Get one users profile

http://localhost/codeigniter/index.php/example_api/user/id/1

Get a list of users in HTML format

http://localhost/codeigniter/index.php/example_api/users/users/format/html

Try to access an object through an unsupported method

http://localhost/codeigniter/index.php/example_api/user_put/id/1/name/Something

Personally, I would recommend using Matchbox to get your controllers into modules and then put a api.php controller into each module you wish to send over the API.

E.g http://localhost/codeigniter/index.php/news/api/article/id/465

As you can see there is plenty of flexibility here. You can use any of the following formats too simply by appending /format/json to the end of your URL or passing the correct MIME-type:

Within your REST controllers, remember you can access GET parameters through $this->get(), POST parameters through $this->post() and PUT parameters through $this->put().

Let me know what you think of this in the comments, tweet me or use the contact form.

Comments

User comments
  • Gravatar Daniel

    Jun 24, 2010

    Hey thanks for sharing that great library.. I Added a functionality to the _format_xml-method which allows you to specify attributes for each xml-element.
    you do this by adding an associative array with a key named _attributes to your data

    $data = array(
    '_attributes' => array('version' => '0.1'),
    'title' => 'CodeIgniter REST'
    );

    will result in the follwing xml

    <xml version="0.1">
    <title>CodeIgniter REST</title>
    </xml>

    just add this code at line 433:

    if($key == '_attributes') {
    $attributes = $value;
    if(is_array($attributes)) {
    foreach($attributes as $name => $attribute) {
    $structure->addAttribute($name, $attribute);
    }
    }

    continue;
    }

  • Gravatar Daniel

    Jun 13, 2010

    hopefully someone can help me ... I have problems with german special characters like "ä" when using xml/json. HTML and csv works fine everything is UTF8.
    xml i get following format error
    XML Parsing Error: undefined entity
    Line Number 2, Column 29:<xml><item>Universität
    html
    Universität Hannover

    thanks daniel

  • Gravatar http://philsturgeon.co.uk/

    Jun 12, 2010

    Dan: I am using this code as a test and I cannot recreate an error (http://pastie.org/1001926). This will only be your browser bitching anyway, the same data is sent as plain text and cURL does not care about valid/invalid XML.

    Mjsilva: Good luck, steer clear of the built in CI output cache as it is no help at all. IMO caching of REST content should be handled on the client side, which is very easy to do with my Cache library.

  • Gravatar Mjsilva

    Jun 11, 2010

    Hey Phill,

    I've been using this library like a freak, and I love it, just one thing missing, a cache system, will try to implement myself, I'll repost the result if I'm success.

    Cheers.

  • Gravatar Dan

    Jun 11, 2010

    I have a problem with the xml/json encoding of German characters like ä and I hope someone can give me a hint. HTML/csv output looks good Universität Hannover but if I try xml as output I get
    Line Number 2, Column 29:<xml><item>Universität Hannover
    mysql is utf-8 and header also <?xml version="1.0" encoding="utf-8"?>
    Thanks
    Dan

  • Gravatar Steve B

    May 14, 2010

    Hi Phil,
    I just started playing with your REST Controller, and I'm using the cURL Library you wrote to send my data.

    One quick question is there any way to get all the variables in your REST Controller method using $this->get(), or $this->post();

    Thanks for the library!
    Steve

  • Gravatar Kelly

    Apr 09, 2010

    Great work. Thanks!

  • Gravatar Gabriel

    Apr 04, 2010

    Ugh - I'm such a Neanderthal, I had a stray closing comment outside my PHP declaration. Doh. And this folks is why I try to stay away from closing php declarations!!

  • Gravatar Gabriel

    Apr 04, 2010

    Hi Phil - No need to reply on my question, I will simply reverse engineer what you have written (on github) to figure what went wrong. Kick-ass work on this man.

  • Gravatar Gabriel

    Apr 04, 2010

    Hi Phil - great work on a RESTful component for CI. Was wondering, would you happen to know why I'm getting '*/' as part of my response data? Is that zero byte or maybe something with mod_rewrite?

    regards.

  • Gravatar Taner Ozdas

    Mar 26, 2010

    Very helpful information about codeigniter and REST. I have a plan to implement to one of my site. Thanks

  • Gravatar Abraham Estrada

    Feb 18, 2010

    What is the best way to change the $basenode from the $this->response method?

  • Gravatar Wahyusumartha

    Jan 08, 2010

    hello how to implement post request in REST with codeginiter ?? thanks

  • Gravatar Rajeev

    Dec 21, 2009

    Good work!!! :)

  • Gravatar Ed

    Dec 08, 2009

    Phil, Good work! FYI update your link for:

    http://localhost/codeigniter/index.php/example_api/users/users/format/html

    have an extra users/users. makes the result always xml.

  • Gravatar Phil Sturgeon

    Dec 02, 2009

    @Terwillagher Willikers: Thanks for the heads up, I have have updated the link and the example.

  • Gravatar Terwillagher Willikers

    Dec 01, 2009

    1. Link to rest config file is borked. Correct link is:
    http://github.com/philsturgeon/codeigniter-restserver/raw/master/application/config/rest.php

    2. After install a quick successful test is:
    http://localhost/codeigniter/index.php/example_api/user/id/1
    (not http://localhost/codeigniter/index.php/example_api/user/id/435)

  • Gravatar Moos3

    Nov 15, 2009

    I'm trying to implement this in one of my projects and I made all the functions like in the example but when I try to access them using api/get_clips/format/html or xml its just a white page. I added the following to the routes.php $route['api/:any'] = 'api'; so it knows to use the api controller. can you help with this?

  • Gravatar Lewis

    Nov 11, 2009

    if your having trouble with cache pages, and your unable to add a cache buster to the url then can add this to the response method

    $this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate");

    IE7 will respect the directive and refresh

  • Gravatar Nicholas

    Nov 09, 2009

    Hello Phill great stuff, but I am getting an error in the xml your code outputs

    XML Parsing Error: not well-formed
    Location: http://localhost/codeigniter/index.php/example_api/users/users/format/html
    Line Number 1, Column 2:??<?xml version="1.0" encoding="utf-8"?>
    -^

  • Gravatar Muser

    Oct 21, 2009

    Sorry the last message I posted haven been trimmed.

    Forget it. Now It works ok when I've upgraded my php version (I was using php 5.1.4). Now with php 5.2.11 works very well.

  • Gravatar Josh Giese

    Oct 21, 2009

    wow, this is great. The community surrounding CodeIgniter is another reason this framework rocks. Thank you for this contribution. I'm working on an iPhone app, and I need to build out the services this connects to. Your code is going to be the foundation for that. Thanks again.

  • Gravatar Muser

    Oct 18, 2009

    Hi I get the following xml when I query users:

    <xml>



    </xml>

  • Gravatar Phil Sturgeon

    Sep 02, 2009

    Mario: Yes query strings are available via $this->get() in the ame way as the URI segments.

    Dan S: Tweet me and i'll follow you. Sadly thats the way you can DM me.

  • Gravatar Dan S

    Aug 01, 2009

    Phil, thanks for this... just started following you on Twitter but really can´t work out how to send a direct message!

    Was wondering... the rest.php seems to point to rest_controller.php on this page

    Sorry if it is a stupid question... im not particularly experienced with codeigniter but trying to get a REST interface up to develop some ning apps.

    Cheers, Dan

  • Gravatar Mario

    Jun 23, 2009

    Can query strings be used too, such as
    ?q1=...&q2;=...

  • Gravatar Phil Sturgeon

    Jun 19, 2009

    I'm glad this has helped you Jared. I have e-mailed you a few details but just to let other readers know; this has been updated with a new version of the Rest Server which can be found on GitHub (links in the article).

    This new version supports HTTP Basic & Digest Authentication via the config/rest.php file.

  • Gravatar Jared

    Jun 12, 2009

    hey, i just wanted to say thanks for developing rest for CI. I am just starting a web services implementation on a project i'm working on and your timing couldn't be better.
    I wanted to let you know as I've been working with your files, there were a couple of small items I changed to get everything working on my end.

    1. I added all of the api files in a subdirectory of my controllers. In doing so, I had to change $this->uri->uri_to_assoc() to $this->uri->ruri_to_assoc() to properly map the uri associations. this will also apply to any other type of routing changes someone might apply.

    2. The method var_export in function _php() should have the second param set to true to return the value instead of dumping it in the function.

    Other than those two items everything appears to be working flawlessly! I also implemented the basic auth you're working on in the forums.

Post a comment