How to build a RESTful API?

The issue is this: I have a web application that runs on a PHP server. I'd like to build a REST api for it.
I did some research and I figured out that REST api uses HTTP methods (GET, POST...) for certain URI's with an authentication key (not necessarily) and the information is presented back as a HTTP response with the info as XML or JSON (I'd rather JSON).

My question is:

  • How do I, as the developer of the app, build those URI's? Do I need to write a PHP code at that URI?
  • How do I build the JSON objects to return as a response?

  • Here is a very simply example in simple php.

    There are 2 files client.php & api.php . I put both files on the same url : http://localhost:8888/ , so you will have to change the link to your own url. (the file can be on two different servers).

    This is just an example, it's very quick and dirty, plus it has been a long time since I've done php. But this is the idea of an api.

    client.php

    <?php
    
    /*** this is the client ***/
    
    
    if (isset($_GET["action"]) && isset($_GET["id"]) && $_GET["action"] == "get_user") // if the get parameter action is get_user and if the id is set, call the api to get the user information
    {
      $user_info = file_get_contents('http://localhost:8888/api.php?action=get_user&id=' . $_GET["id"]);
      $user_info = json_decode($user_info, true);
    
      // THAT IS VERY QUICK AND DIRTY !!!!!
      ?>
        <table>
          <tr>
            <td>Name: </td><td> <?php echo $user_info["last_name"] ?></td>
          </tr>
          <tr>
            <td>First Name: </td><td> <?php echo $user_info["first_name"] ?></td>
          </tr>
          <tr>
            <td>Age: </td><td> <?php echo $user_info["age"] ?></td>
          </tr>
        </table>
        <a href="http://localhost:8888/client.php?action=get_userlist" alt="user list">Return to the user list</a>
      <?php
    }
    else // else take the user list
    {
      $user_list = file_get_contents('http://localhost:8888/api.php?action=get_user_list');
      $user_list = json_decode($user_list, true);
      // THAT IS VERY QUICK AND DIRTY !!!!!
      ?>
        <ul>
        <?php foreach ($user_list as $user): ?>
          <li>
            <a href=<?php echo "http://localhost:8888/client.php?action=get_user&id=" . $user["id"]  ?> alt=<?php echo "user_" . $user_["id"] ?>><?php echo $user["name"] ?></a>
        </li>
        <?php endforeach; ?>
        </ul>
      <?php
    }
    
    ?>
    

    api.php

    <?php
    
    // This is the API to possibility show the user list, and show a specific user by action.
    
    function get_user_by_id($id)
    {
      $user_info = array();
    
      // make a call in db.
      switch ($id){
        case 1:
          $user_info = array("first_name" => "Marc", "last_name" => "Simon", "age" => 21); // let's say first_name, last_name, age
          break;
        case 2:
          $user_info = array("first_name" => "Frederic", "last_name" => "Zannetie", "age" => 24);
          break;
        case 3:
          $user_info = array("first_name" => "Laure", "last_name" => "Carbonnel", "age" => 45);
          break;
      }
    
      return $user_info;
    }
    
    function get_user_list()
    {
      $user_list = array(array("id" => 1, "name" => "Simon"), array("id" => 2, "name" => "Zannetie"), array("id" => 3, "name" => "Carbonnel")); // call in db, here I make a list of 3 users.
    
      return $user_list;
    }
    
    $possible_url = array("get_user_list", "get_user");
    
    $value = "An error has occurred";
    
    if (isset($_GET["action"]) && in_array($_GET["action"], $possible_url))
    {
      switch ($_GET["action"])
        {
          case "get_user_list":
            $value = get_user_list();
            break;
          case "get_user":
            if (isset($_GET["id"]))
              $value = get_user_by_id($_GET["id"]);
            else
              $value = "Missing argument";
            break;
        }
    }
    
    exit(json_encode($value));
    
    ?>
    

    I didn't make any call to the database for this example, but normally that is what you should do. You should also replace the "file_get_contents" function by "curl".


    In 2013, you should use something like Silex or Slim

    Silex example:

    require_once __DIR__.'/../vendor/autoload.php'; 
    
    $app = new SilexApplication(); 
    
    $app->get('/hello/{name}', function($name) use($app) { 
        return 'Hello '.$app->escape($name); 
    }); 
    
    $app->run(); 
    

    Slim example:

    $app = new SlimSlim();
    $app->get('/hello/:name', function ($name) {
        echo "Hello, $name";
    });
    $app->run();
    

    That is pretty much the same as created a normal website.

    Normal pattern for a php website is:

  • The user enter a url
  • The server get the url, parse it and execute a action
  • In this action, you get/generate every information you need for the page
  • You create the html/php page with the info from the action
  • The server generate a fully html page and send it back to the user
  • With a api, you just add a new step between 3 and 4. After 3, create a array with all information you need. Encode this array in json and exit or return this value.

    $info = array("info_1" => 1; "info_2" => "info_2" ... "info_n" => array(1,2,3));
    exit(json_encode($info));
    

    That all for the api. For the client side, you can call the api by the url. If the api work only with get call, I think it's possible to do a simply (To check, I normally use curl).

    $info = file_get_contents(url);
    $info = json_decode($info);
    

    But it's more common to use the curl library to perform get and post call. You can ask me if you need help with curl.

    Once the get the info from the api, you can do the 4 & 5 steps.

    Look the php doc for json function and file_get_contents.

    curl : http://fr.php.net/manual/fr/ref.curl.php


    EDIT

    No, wait, I don't get it. "php API page" what do you mean by that ?

    The api is only the creation/recuperation of your project. You NEVER send directly the html result (if you're making a website) throw a api. You call the api with the url, the api return information, you use this information to create the final result.

    ex: you want to write a html page who say hello xxx. But to get the name of the user, you have to get the info from the api.

    So let's say your api have a function who have user_id as argument and return the name of this user (let's say getUserNameById(user_id)), and you call this function only on a url like your/api/ulr/getUser/id.

    Function getUserNameById(user_id)
    {
      $userName = // call in db to get the user
      exit(json_encode($userName)); // maybe return work as well.
    }
    

    From the client side you do

        $username = file_get_contents(your/api/url/getUser/15); // You should normally use curl, but it simpler for the example
    // So this function to this specifique url will call the api, and trigger the getUserNameById(user_id), whom give you the user name.
        <html>
        <body>
        <p>hello <?php echo $username ?> </p>
        </body>
        </html>
    

    So the client never access directly the databases, that the api's role.

    Is that clearer ?

    链接地址: http://www.djcxy.com/p/1254.html

    上一篇: 在jsp文件中输入application / json

    下一篇: 如何构建RESTful API?