Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create API using CakePHP

Tags:

php

cakephp

I have a simple CakePHP application that allows a user to create and edit posts. And I'm looking to get the application into PhoneGap at some point in the future.

Therefore I have created an API that spits out JSON for use in AJAX requests, but I get the feeling I'm doing it wrong as I'm not using REST or doing anything any different that sets it apart from other code in the controller.

e.g. (NOTE: I'm missing the part about turning it into JSON for this example)

class ApiController extends AppController {

    function index() {
        $posts= $this->Post->find('all');
        $this->set(compact('posts'));
    }
}

To create a url like: domain.com/api/posts/all (would create custom route to achieve this) which I can then call using AJAX to use in my mobile app.

Now my question is what differently would doing it using REST be? I'm very much a newbie to building applications and my strengths are in front-end rather than back-end development so any pointers, help with this would be much appreciated.

like image 761
Cameron Avatar asked Aug 08 '12 12:08

Cameron


2 Answers

Turning on REST in CakePHP basically routes proper HTTP methods to actions. So, a GET request would be routed to an index or view action, a DELETE request routed to the delete action, and so forth.

This creates a very easy endpoint for people using your API. Then when calling this endpoint, depending on the HTTP method Cake will route it to the proper action (forgive any HTTP request syntax errors):

// single endpoint
http://example.com/api/posts

A GET request that routes to /posts/index.json

GET /api/posts.json HTTP/1.1
Host: example.com

A POST request that routes to /posts/edit/1.json

POST /api/posts/1.json HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Content-Length: 24

data[Post][name]=updated

Reading this will answer most of your questions: http://book.cakephp.org/2.0/en/development/rest.html

like image 180
jeremyharris Avatar answered Oct 18 '22 23:10

jeremyharris


If your concern is to be true to the Rest principals.

Then, there are usually 4 points to keep in mind:

  • Base URI for the web service
  • The Internet media type of the data supported by the web service.
    This is often JSON, XML or YAML but can be any other valid Internet media type.
  • The set of operations supported by the web service using HTTP methods (e.g., GET, PUT, POST, or DELETE).
  • The API must be hypertext driven

See, http://en.wikipedia.org/wiki/Representational_state_transfer for more details.

Now, with that said, I would suggest changing your above code to be some what close to the below pseudo codes.

1) The existence of resources is key, think of your post(s) as a collection of resources that can be accessed by a URI.(authentication & authorization are other concerns that you might also want to handle):

api.domain.com/resources/posts => This URI points to a collection of Posts

2) The set of operations that you will want to support using HTTP methods/verbs need to defined, as an example we might want to retrieve just one member of the collection by doing this:

api.domain.com/resources/posts/12

Below are request header & body that could be found in an incoming request for this URI:

Accept: application/json
Content-Type: application/json
Request Url: http://api.domain.com/resources/posts/12
Request Method: GET

Your application should be able to handle that type of request, without the need of stipulating the operation in the URI, bringing us back to point (1),

rather than having a URI written this way:

domain.com/api/posts/all

Your URI should be model this way:

resources/posts/12 as resources/type/item to retrieve one member from the collection,
resources/posts as resources/type to work with the entire collection.

Here's an example of codes:

Common abstract class Here you could implement some common tasks. If, you are using a service based implementation this could also be accomplished by a service.

abstract class ResourcesController extends AppController {
}


class PostResourcesController extends ResourcesController {

    /**
     * By the time this method is called in your controller/class, you already know
     * that the HTTP method is GET.
     * 
     * @param Request\$_GET $request A request instance
     * @param int           $postId  The post ID to retrieve
     *
     * @return Response A reponse instance
     */
    function getPost(Request $Request, $postId = null)
    {
      /**
       * Here you can use the request object to get
       * the response content type    
       * the requesting client accepts. Example JSON or XML.
       */

       /**
        * using the $postId you can then query your database  
        * to retrieve a post with that ID or use a sort of 
        * service.
        */

         /**
         * Once you implemented a you logic
         * you can build a response to return.
         */
    }
}

This code is incomplete, but I hope it gives you an idea of what a real Restful API might look like.

The key it to make sure that
"the application can interact with a resource by knowing two things: the identifier of the resource and the action required".

Hopefully, this helped.

like image 26
bluetazmanian Avatar answered Oct 18 '22 23:10

bluetazmanian