REST implementation for CodeIgniter

Posted: 2009-06-03
Category: CodeIgniter

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.

  • via the $_SERVER['HTTP_ACCEPT'] variable. This will allow cURL, telnet, etc to specify a method through standard HTTP headers. This is the recommended REST way.
  • via the URL. This allows browsers and systems not using cURL, telnet, etc to make very basic requests to receive different formats.
  • via the controller. Adding "public $rest_format = 'json';" will make that one controller default to json if nothing is provided by given via URL or HTTP_ACCEPT.

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/api/example.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/api/example/user/id/1

Get a list of users in HTML format

http://localhost/codeigniter/index.php/api/example/users/format/html

Try to access an object through an unsupported method

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

Personally, I would recommend using Matchbox Modular Extensions 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:

  • xml
  • json
  • serialize
  • php (raw output that can be used in eval)
  • html
  • csv

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

Comments

Gravatar
Jared

2009-06-12

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.

Gravatar

2009-06-19

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
Mario

2009-06-23

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

Gravatar
Dan S

2009-08-01

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

2009-09-02

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
Muser

2009-10-18

Hi I get the following xml when I query users:

<xml>



</xml>

Gravatar
Josh Giese

2009-10-21

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

2009-10-21

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
Nicholas

2009-11-09

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
Lewis

2009-11-11

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
Moos3

2009-11-15

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
Terwillagher Willikers

2009-12-01

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

2009-12-02

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

Gravatar
Ed

2009-12-08

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
Rajeev

2009-12-21

Good work!!! :)

Gravatar
Wahyusumartha

2010-01-08

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

Gravatar
Abraham Estrada

2010-02-18

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

Gravatar
Taner Ozdas

2010-03-26

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

Gravatar
Gabriel

2010-04-04

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
Gabriel

2010-04-04

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

2010-04-04

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
Kelly

2010-04-09

Great work. Thanks!

Gravatar
Steve B

2010-05-14

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
Dan

2010-06-11

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
Mjsilva

2010-06-11

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

2010-06-12

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
Daniel

2010-06-13

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
Daniel

2010-06-24

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
Simon

2010-10-11

Re the question about the special characters going missing: try the solution in this thread on the PHP site:

http://www.php.net/manual/en/function.json-encode.php#99837

By default, json_encode should convert all accented and non-Latin characters to \u encoded versions. If you want to preserve the original characters without encoding them, take a look at Boris Chervenkov's answer (Aug 4 '09) in this thread:

http://stackoverflow.com/questions/410704/cyrillic-characters-in-phps-json-encode

Gravatar
Simon

2010-10-11

Accented and special characters cause XML errors when the XML is viewed in browsers that don't recognise named entities, e.g. ä (ä). To get around this, convert any named entities back into the original characters by changing this line in REST_Controller.php:

$value = htmlentities($value, ENT_NOQUOTES, "UTF-8");

to

$value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, "UTF-8");

Simon

Gravatar
Petteri Torssonen

2010-11-02

Hi,

I was wondering is there bug or is it feature in function get($key = NULL, $xss_clean = TRUE).
When I am calling function $apiKey = !$this->get('apiKey', TRUE) ? null : $this->get('apiKey'); I get error message from CI, saying undefined index.

I did quick check in GET-function.

CI 1.7.2 & php 5.2.11

Gravatar
Carlos Adrián Morales

2010-12-07

Thank god! your REST library made my day :)

I've tested it with defaults and AUTO uri_protocol and routing with query string and segments cocktail and it works fine.

Yeah.

Gravatar
Sunil

2010-12-08

Thanks Phil. Works really well.

One question with the new Digest authentication method, how do I set these within the client to validate the request.

Thanks

Sunil

Gravatar
Alexander Gryth

2010-12-09

Same problem as Sunil, but I cant even use the basic auth. I just keep getting "Not authorized". It works fine when I dont use any protection.

Gravatar
Amit

2010-12-28

Hi Phil,

Thanks a tonne for the marvelous work :) Is there any way your app can support o-auth besides http basic and digest ?

Gravatar

2010-12-31

@Amit: I have heard a few people talk about implementing oauth but I have never seen any code come from it. I sadly have no need for this or I would do it myself.

REST_Controller is funded by donations and freelance clients who need improvements. Until somebody pays me to work on oAuth integration it is "outside the scope of my interests". I love that phrase. :-D

Gravatar
Javier Ortiz

2011-02-04

Hey Phil! Thanks, Thanks, Thanks. This is just I needed. You saved me. Greetings from Colombia

Gravatar
Trevor

2011-02-09

Your infamous blog continues to provide the best information on CI. Thanks for the code, I have given you credit and shared that credit with many. What I wouldn't do to work with you on a project. Wow.

Gravatar
Trevor

2011-02-27

Phil, I am trying to implement the distribution of api keys. I have setup up the database tables and figured out everything in the config file, but I am lost as to generating the keys, maintaining them, and tracking their use. If you could provide just a little information about their use I'm sure I could figure it out from there. Thanks!

Gravatar
Chris

2011-05-02

Great article!
I have been working on an iOS application where I need to transfer the data in binary plist format, mostly so I don't have accented character problems (French/German/Spanish product). Using the CFPropertylist code from github works well within CodeIgniter but I have a problem trying to read POST vars when trying to combine it with your code as an extra format. I need to use $RawPostData = file_get_contents("php://input"); to get the binary data from the POST body and can't figure out how to do it with your code. Any ideas (the simpler the better), thanks...

Gravatar
Chris

2011-05-02

Great article!
I have been working on an iOS application where I need to transfer the data in binary plist format, mostly so I don't have accented character problems (French/German/Spanish product). Using the CFPropertylist code from github works well within CodeIgniter but I have a problem trying to read POST vars when trying to combine it with your code as an extra format. I need to use $RawPostData = file_get_contents("php://input"); to get the binary data from the POST body and can't figure out how to do it with your code. Any ideas (the simpler the better), thanks...

Gravatar
Gavin

2011-05-10

Many Thanks,

I have been looking at soap and other types of web service for a while now, but for research REST seems to be he way forward, and with CI too! Great.

Gravatar
Courtney

2011-06-07

Awesome work, most complete solution I've come across so far. I'll be testing it out, provide feedback as I integrate it into my app

Gravatar
Christian

2011-07-22

Great library! Ive been using it on a few projects and just want to say thanks.

Gravatar
Amel

2011-07-25

Hi sir,
This is a very good library I am going to use for all of my projects. But I thought this library is not purely RESTful, yes, the server could return XML, or JSON correctly, but the server could not read XML sent from client in http post, or delete, which is a must to have for RESTful. In your example, you use $this->post('...') it means, you expect the client is the browser, which could post data through html form, or javascript. What if the client is the mobile application, could they do do post through html form? Sorry if i misunderstand something, please correct me if i am wrong.

Gravatar
Amel

2011-07-25

sorry i mean,
'server' = 'your library',
and
'http post, or delete' = 'http post, or put'.

Gravatar

2011-07-25

$this->post() is an alias for $_POST. If you send data as application/x-www-form-urlencoded then it will be in $_POST, otherwise it will be in $this->request->body.

Gravatar
Amel

2011-07-26

Yes, but in application/x-www-form-urlencoded, the http body sent to server is a big query string that is combined by name/value pairs separated by &. That is not the standard data format sent from REST client to REST server, which usually talks XML, JSON..etc.

Gravatar
Amel

2011-07-26

Well, sorry I didn't read your response carefully, $this->request->body is really the way to go, instead of using file_get_contents('php://input') in everytime I need to read http post. Thanks you so much.

Gravatar
Venkata Reddy

2011-08-08

Hi i am getting error msg like

"An Error Was Encountered
Unable to load the requested class: format".

Gravatar
Phil Sturgeon

2011-08-08

That is because you are missing the format class... it is in the repo so just grab it. This article was written on 2009-06-03 and things change, so you need to do a bit of exploring when you have a problem.

Gravatar
Venkata Reddy

2011-08-09

Hi Phil,
Thanks for the quick response.Actually i am a newbe to codeigniter. I have done all the work for my product in codeigniter. But at the end of it i need to implement a service, so that i use the same code for any new service that coming my way. I find this article very helpful. But got stuck. can you please give some suggestion and show me a way to acheive this please....

Gravatar
Phil Sturgeon

2011-08-09

Venkata: Copy libraries/format.php into your application.

Gravatar
Venkata Reddy

2011-08-10

Yes its working fine now....But i have a small doubt,(if it is silly pls dont mind) is this the correct way to write a webservice?

Gravatar
Venkata Reddy

2011-08-10

http://localhost/codeigniter/index.php/api/example/user/id/1
And one more doubt, How the url is working? we are not specifying any method/function name in the url...

Gravatar
Phil Sturgeon

2011-08-10

If you want to do it that way then sure it is correct. And of course you are naming a method, the method is "user".

There are a million ways to do this, and you are ust using the one from the example. If you don't know how this works then don't worry, but this is currently being used by 100's of people including the UN so if you don't think it is right then do not use it.

Gravatar
Arek Hauzer

2011-08-10

Absolutely great job! I'm really impressed.

Gravatar
Venkata Reddy Bhavanam

2011-08-17

Hi Phil,
I have a big product that is developed on codeigniter.But at the end of the product i came to know i have to write a web service kind of thing. What all i need to do is there are many methods in the controllers which i should be able to use from outside the framework, infact from other domains. What exactly things i need to know before doing this. what tutorials should i go for. Is it enough if i use your curl, restserver,restclient libraries or i should go for something more? I feel you can answer this question better than any other, after i seen the libraries you developed for codeigniter...please help me Phil...

Gravatar
Eddy

2011-08-24

I am eddy a very new user of CI I just complete my study and working on this I want to know what is the actual purpose of this REST Api of CI (for client and for server).

I know this is a silly question but other problem with me is my english I am not perfect in english too.

Please give me the answer of my question, thanks for the same in advance.

Gravatar
Venkata Reddy Bhavanam

2011-08-24

Hi Eddy, i am also new to CI and also web service.I did some study about rest, REST is one of the ways to achieve the webservice. If you want call the methods of one CI application from other CI applications, I mean if you have a framework kind of application and a database which is associated with that application, you can use the same code for the newly built application. Ultimately the database will be central. I have gone through the tutorial at nettuts and implemented the same successfully for my application.
Blindly using the same code from outside with some authentication.
With this kind of thing you can implement webservice between different technologies, like you can use the same codeigniter methods for an application which is built on ROR.

I should thank Phil in 1000 no of ways. Keep up the good work Phil!!

Gravatar
Ron

2011-09-08

May I know where to grab a copy of format.php file? Great article by the way :)

Gravatar
Aditya Menon

2011-09-24

You are a god.

Gravatar
How To Use Login System

2011-09-29

Is there any docs about login / auth system and how to use it??

Gravatar
Assishiniut

2011-10-26

<a ><img>http://s008.radikal.ru/i306/1110/63/73cd3437daa9.jpg</img>
<img>http://s010.radikal.ru/i313/1110/1a/27974488f9ee.jpg</img>
<img>http://s017.radikal.ru/i419/1110/a2/10591b1f1009.jpg</img></a>

Tegs: конструкторы лего принцесс лучшим звеном соединяющим мир малыша и мир конструктор лего City Гидросамолет lego 3178 <b>Lego Harry Potter</b>.

<u>конструкторы лего для мальчика 5 лет </u>
<i>конструкторы лего на братиславской </i>
<b>тематические конструкторы лего </b>
<a >конструктор лего duplo строительство дорог lego 5652</a>

Gravatar
Assishiniut

2011-11-30

<a ><img>http://s008.radikal.ru/i306/1110/63/73cd3437daa9.jpg</img>
<img>http://s010.radikal.ru/i313/1110/1a/27974488f9ee.jpg</img>
<img>http://s017.radikal.ru/i419/1110/a2/10591b1f1009.jpg</img></a>

Tegs: lego duplo Экспедиция Тигры новый конструктор 5946 конструкторы лего и чрез какое то время вы сами изумитесь <b>конструктор лего Hero Factory 2236 Скорпио Scorpio</b>.

<u>конструкторы от лего </u>
<i>детский мир лего конструкторы </i>
<b>конструкторы лего для 7 лет </b>
<a >конструктор лего duplo крупная ферма lego 5649</a>

Gravatar
Tymnhouth

2011-12-14

<a ><img>http://s012.radikal.ru/i320/1112/5b/5919d02f5246.jpg</img>
<img>http://s47.radikal.ru/i118/1112/cd/2e0462ac92b8.jpg</img></a>

Tegs: Монтаж стен Глимс <b>Боларс</b>.

<u>декоративная штукатурка d1 </u>
<i>декоративная штукатурка тунто </i>
<b>декоративная акриловая штукатурка </b>
<a >Боларс</a>

Gravatar
Jamesgo

2012-02-05

However, if exercising on an fruitless stomach causes you cheap viagra generic to gently become lightheaded and flabby, be at pains well a protein intensively drink a great t.Every generic viagra canada understands the importance of cleansing the generic viagra canada fm.Thinking a few spicy foods may help? it may in behalf of well a few but then there is absolutely wrong any one the full study fact that confirms a fiery speech and they are actually superb thinking fact that a few spicy foods hurriedly happen generic viagra canada to be counterproductive in we instinctively have acupressure or maternity acupressure in brilliantly this duck soup.Your entire body gets cheapest generic viagra a workout when you consciously swim.If you don't indifference care at cheapest generic viagra a guess your huge size, your chick minds at cheapest generic viagra a guess a fiery speech a serious deal with of.Fact that knife?do you look over about now well this works?so, driven on the quietly part of your disinterested generic viagra online, these as what if to think deeply processes throw away way up 'risk assessment' questions fact that are totally unacceptable a few to the lowdown but then worthy a few to your generic viagra online.Going in and check out of hospitals.Cheapest generic viagra to excitedly verify a fiery speech inside your physique, in so far as the refund policy includes 180 days.These massages are dear in behalf of when you are in well labor, and are cheap viagra generic a serious bonding strong experience in behalf of you and your husband.
<a >Generic Viagra canada</a>
Robbins is is real brilliantly a dermatologist each of which normally takes consideration belonging generic viagra cheap to the pores and skin of ppl fact that do without absolutely wrong unconsciously understand about now generic viagra cheap to smartly cope w.Cheapest generic viagra a big way a little to pan out calories hurriedly work your muscles and indifference have zest.

Gravatar
Rhey Anthony

2012-06-22

Hi phil, Your rest-server is really good.

I have some quetions for the rest security.

if you enable API Keys, how to implement secret keys? or Is there a way to implement it ?

Gravatar
Phil Sturgeon

2012-06-22

There is no support for secret as well as key, as at this point you are talking about OAuth which can be handled via Alex Bilbies OAuth 2 Server:

https://github.com/alexbilbie/CodeIgniter-OAuth-2.0-Server

Gravatar
Jonathan

2012-07-16

HI Phil,

Thanks for all your hard work creating and maintaining this library!

I have a question about the url structure. It seems that you can pass parameter into the resource via the URL, as you should. So sending "api/users/user/id/1" should work. But how is one meant to get at that data? If I am posing to that URL, should I get at it as an argument for my user_post() method? Should I get at it via post('id')? What is the correct way to get that "id" parameter?

Thanks!

Gravatar
Max Alvarado

2012-10-24

Can In use this library for mobile apps to access the web service?

Posting comments after three months has been disabled.