[CI] using the CodeIgniter framework to build RESTful API services

Source: Internet
Author: User
Tags representational state transfer response code vcard codeigniter

In August 2011, I wrote a blog, "using the CodeIgniter framework to build RESTful API services," describing restful design concepts and how to implement restful APIs using the CodeIgniter framework. Two years later, rest has improved a lot in the past two years. I am not very satisfied with some aspects of the previous blog, so I hope to use this opportunity to write a more complete version.
My project is based on Phil Sturgeon's CodeIgniter REST Server, which follows his own Dbad protocol. Phil's project was great, neat, simple, practical, and very distinctive, addressing two of my own projects: the use of query statements in requests, and the complex authentication methods. As I said earlier, my project is based on Phil's project development, and only one aspect is different: I assign one controller to each resource, instead of a single, large controller for unified management. The benefits of using multiple standalone controllers are simpler and easier to maintain.
The complete project source code can be downloaded in awhitney42/codeigniter-restserver-resources.
Before we go deep into the rest, let's review the concept of testful. Rest full name representational state Transfer, Chinese can be translated as follows: The presentation Layer status transformation is a Network Service Architecture tool, not just a set of interface specifications.
Using nouns instead of verbs your restful interface should provide access rather than methods.
So, this is not advisable:
/createcustomer
/getcustomer?id=666
This should be the case:
Post/customers
get/customers/666
Everything should have a idrest. One of the virtues of simplicity is that, to a certain extent, rest is just a collection of URIs, each of which requires a unique ID as an identity.
get/customers/666
get/products/4234
Use verbs to manipulate in rest, use different HTTP verbs for the operation of the add and revise check:
[TD]
Verb manipulation
POST Create a new resource
GET reads a resource
PUT updates A resource
Delete Deletes a resource
Using the rest Service's mapping table to design the interface, you can easily get started while developing the client without having to understand the meaning of the interface. This set of standards is well-suited for rest and conforms to the core design concepts of service-oriented architecture (SOA): Service extraction, loose coupling, reusability, discoverable, and robustness.
Through this consistent mapping, the client also knows which verb is idempotent (idempotent). Idempotent means that the operation can be repeated several times, and the same result will be obtained each time. Referring to the HTTP specification, GET, put, and delete operations are idempotent, and post operations are not idempotent. This is why you use post for add operations in rest, and you use put for update operations.
To link things up. One of the core concepts in rest is Hateoas (hypermedia as the engine of application state), or "Hypermedia is the application status engine". This means that you should always use links (hypermedia) to get resource information, and then the client can get to different resources through this link.
Therefore, the related resource should return a link instead of returning the contents of the entire resource.
That is, this is the case:

<officer id= "1" >   <name>james T. kirk</name>   <rank>Captain</rank>   < subordinates>      <link ref= "HTTP://NCC1701/API/OFFICERS/2" >      <link ref= "http://ncc1701/api/ OFFICERS/3 ">   </subordinates></officer> not: <officer id=" 1 ">   <name>james T. kirk</name>   <rank>Captain</rank>   <subordinates>      <officer id= "2" >         <name>Spock</name>         <rank>Commander</rank>      </officer>      < Officer Id= "3" >         <name>doctor Leonard mccoy</name>         <rank>Commander</rank>      </officer>   </subordinates></officer>

The link that returns the resource should use the full URI address instead of the relative path, which requires the client to request the current state of these resources and maintain the HATEOAS principle. The benefit of using a full URI address is that the client does not need to have additional knowledge of the API-related content, simply to access these links.
Provides multiple resource representations the R in rest represents representational, the presentation layer, which means that the rest service should provide a different representation to fully support different client requests. In an HTTP request, the server can return resources by a specified representation, and the rest service should use a standard representation so that the information between the clients is interoperable.
For example, you can request data in XML format as follows:
get/customers/666
Accept:application/xml
or vcard format:
get/customers/666
Accept:application/vcard
or PDF format:
get/customers/666
Accept:application/pdf
or the custom format:
get/customers/666
Accept:application/vnd.mycompany.customer-v1+json
Using a status code as a status code to reply to HTTP provides a standardized scheme for responding to the status of a request.
[TD]

Meaning explanation
OK to confirm that the get, put, and delete operations were successful
201 Created Confirm the post operation was successful
304 Not Modified is used for conditional get access, which tells the client that the resource has not been modified
The bad request is typically used for post or put requests, indicating that the requested content is illegal
401 Unauthorized requires authorization
403 Forbidden No access rights
404 Not Found There are no resources on the server
405 Method Not allowed request methods cannot be used to request the appropriate resource
409 Conflict access and current state conflict
Codeignitercodeigniter is a popular MVC framework that is well suited for RESTful API development. The controller handles the client's request and returns the content, and the model carries out a pruning (CRUD) operation that the view uses to handle the presentation of the resource. In this case, however, we do not use the model, but directly with the controller format, so that the whole project is cleaner and simpler.
The code can be obtained directly from GitHub: Codeigniter-restserver-resources.
In the following example, we use the Rest_controller library, which inherits from the native Ci_controller. It can do most of the tedious work: processing requests, invoking modules, formatting content, and returning data. Each of your resource controllers should inherit from the Rest_controller class.
Let's take a look at an example and let's say we want to provide a restful interface for a widgets resource:

Class Widgets extends Rest_controller
The first function in the Get () Widgets class is get (), which is used to respond to a GET request for HTTP. This function calls the parent class's protected function, _get (), to get the parameter ID in the request. The function then uses Widgets_model to call Getwidgets () or Getwidget ($id) method based on whether there is a parameter ID, and the return value of the model will be returned through the response () function of the parent class. The returned content contains the corresponding status code and the data in accordance with the format.

[Mw_shl_code=php,true]function get () {        $id = $this->_get (' id ');    if (! $id)    {        $widgets = $this->widgets_model->getwidgets ();                                if ($widgets)            $this->response ($widgets, $);//being the HTTP response code        else            $this- Response (Array (' ERROR ' = ' couldn\ ' t find any widgets! '), 404);    }    $widget = $this->widgets_model->getwidget ($id);    if ($widget)        $this->response ($widget, $);//being the HTTP response code    else        $this- Response (Array (' ERROR ' + ' Widget could not is found '), 404);}

Curl is a good command-line tool that we can use to test the rest service and return a JSON-formatted data:

The following will be returned:
http/1.1 OK
status:200
Content-type:application/json
{"1": {"id": 1, "name": "Sprocket"}, "2": {"id": 2, "name": "Gear"}}
Requesting a specific resource is also simple, this time we're going to request a widget with ID 2 and return it in XML format:
$ curl-i-H "accept:application/xml"-X GET HTTP://FOO.COM/INDEX.PHP/API/WIDGETS/ID/2
The following content is returned:

http/1.1 OK
status:200
Content-type:application/xml
<?xml version= "1.0" encoding= "Utf-8"?>
<xml><id>2</id><name>gear</name></xml>
If a resource that does not exist is requested, a 404 error code is returned:

http/1.1 404 Not Found
status:404
Content-type:application/xml
<?xml version= "1.0" encoding= "Utf-8"?>
<xml><error>widget could not being found</error></xml>
Post () The next function is post (), which handles the post request to create the widget. The requested data can be obtained through $this->_post_args. The parent class processes the requested data through format.php and puts them into the $this->_post_args. The next post () method calls the Createwidgets ($data) function using the Widgets_model model, and if the data is illegal or requests a conflict, the Widgets_model model throws an exception and returns the contents of the exception. If the call succeeds, the Getwidget ($id) function is called to get the latest widget, which returns the return value along with the status Code of 201 (Created).

Function post () {    $data = $this->_post_args;    try {        $id = $this->widgets_model->createwidget ($data),    } catch (Exception $e) {        //Here the model can th Row exceptions like the following:        //* Invalid input data:                    //   throw new Exception (' Invalid request data ', 400 );        * Conflict when attempting to create, like a resubmit:                    //   throw new Exception (' Widget already exists ', 409) 
    $this->response (Array (' ERROR ' = $e->getmessage ()),                                    $e->getcode ());    }    if ($id) {        $widget = $this->widgets_model->getwidget ($id);        $this->response ($widget, 201); 201 is the HTTP response code    } else        $this->response (Array (' error ' = = ' Widget could not being created '), 
   404);}

  

[CI] using the CodeIgniter framework to build RESTful API services

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.