Как построить RESTful API?

76

Проблема заключается в следующем: У меня есть веб-приложение, которое работает на сервере PHP. Я хотел бы создать REST api для него.
Я провел некоторое исследование, и я понял, что REST api использует HTTP-методы (GET, POST...) для определенного URI с ключом аутентификации (необязательно), и информация представляется обратно как ответ HTTP с информацией как XML или JSON (Я бы предпочел JSON).

Мой вопрос:

  • Как я, как разработчик приложения, создаю эти URI? Нужно ли мне писать PHP-код в этом URI?
  • Как создать объекты JSON для возврата в качестве ответа?
  • 1
    gen-x-design.com/archives/create-a-rest-api-with-php - отличный ресурс по этому вопросу.
  • 0
    Я написал этот блог, содержащий пример кода и инструкции для этого.
Теги:
authentication
rest

7 ответов

64
Лучший ответ

Вот простой пример в простой php.

Есть 2 файла client.php и api.php. Я помещаю оба файла на один и тот же URL: http://localhost:8888/, поэтому вам придется изменить ссылку на свой собственный URL-адрес. (файл может находиться на двух разных серверах).

Это просто пример, он очень быстрый и грязный, плюс прошло много времени с тех пор, как я сделал php. Но это идея апи.

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 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));

?>

Я не делал никакого вызова в базе данных для этого примера, но обычно это то, что вы должны делать. Вы также должны заменить функцию "file_get_contents" на "curl".

  • 0
    Саймон, большое спасибо за твой пример. Я просто хочу быть уверен: предположим, что у меня есть ресурс с именем User, тогда мне нужно поместить файл API в: mydomain.com/api/user Correct?
  • 0
    Вы можете назвать файл так, как хотите. Но да, лучше назвать файл с точным именем. Посмотрите в моем API-файле, я проверяю параметр get и вызываю функцию благодаря этому значению. Вы можете включить user.php и вызвать функцию, которая находится в этом файле, или вы можете поместить файл в api / user и обработать параметры отсюда.
Показать ещё 6 комментариев
32

В 2013 году вы должны использовать что-то вроде Silex или Slim

Пример Silex:

require_once __DIR__.'/../vendor/autoload.php'; 

$app = new Silex\Application(); 

$app->get('/hello/{name}', function($name) use($app) { 
    return 'Hello '.$app->escape($name); 
}); 

$app->run(); 

Тонкий пример:

$app = new \Slim\Slim();
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name";
});
$app->run();
  • 1
    Спасибо. Я использовал Slim, и через несколько минут у меня был запущен API.
  • 0
    Что бы вы посоветовали для более сложных (подробных) apis? Slim - это удобно, но все функции находятся в одном файле, поэтому читаемость довольно сложная.
Показать ещё 1 комментарий
11

Это почти то же самое, что и обычный веб-сайт.

Обычный шаблон для веб-сайта php:

  • Пользователь вводит URL-адрес
  • Сервер получает URL-адрес, анализирует его и выполняет действие
  • В этом действии вы получаете/генерируете каждую информацию, необходимую для страницы
  • Вы создаете страницу html/php с информацией из действия
  • Сервер генерирует полностью html-страницу и отправляет ее пользователю

С помощью api вы просто добавляете новый шаг между 3 и 4. После 3 создайте массив со всей необходимой информацией. Кодируйте этот массив в json и выйдите или верните это значение.

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

Что все для api. Для клиентской стороны вы можете вызвать api по URL-адресу. Если api работает только с вызовом, я думаю, что это можно сделать просто (чтобы проверить, я обычно использую завиток).

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

Но чаще всего используется библиотека curl для выполнения get и post call. Вы можете спросить меня, нужна ли вам помощь с завитком.

После получения информации из api вы можете выполнить 4 и 5 шагов.

Посмотрите файл php для функции json и file_get_contents.

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


ИЗМЕНИТЬ

Нет, подождите, я не понимаю. "PHP-страница API", что вы подразумеваете под этим?

Api - это только создание/восстановление вашего проекта. Вы НИКОГДА не отправляете напрямую результат html (если вы делаете сайт), бросаете api. Вы вызываете api с url, возвращаемой информацией api, вы используете эту информацию для создания конечного результата.

ex: вы хотите написать html-страницу, которая будет приветствовать xxx. Но чтобы получить имя пользователя, вам нужно получить информацию от api.

Итак, предположим, что у вашего api есть функция, у которой есть user_id как аргумент и возвращает имя этого пользователя (скажем, getUserNameById (user_id)), и вы вызываете эту функцию только по URL-адресу, например, вашему/api/ulr/getUser/идентификатор.

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

С клиентской стороны вы выполняете

    $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>

Таким образом, клиент никогда не получает доступ непосредственно к базам данных, а именно к роли api.

Яснее?

  • 0
    +1. Также следует отметить, что API должен установить правильный тип содержимого для ответа. Для json, см. Stackoverflow.com/questions/477816/the-right-json-content-type
  • 0
    Так у меня должна быть на сервере одна php API страница, которая управляет всеми запросами?
Показать ещё 8 комментариев
6

(1) Как я могу создать эти URI? Нужно ли мне писать PHP-код в этом URI?

Нет стандартов для того, как должна быть настроена схема URI API, но она имеет общее значение, которое имеет значения, разделенные символом. Для этого вы можете использовать...

$apiArgArray = explode("/", substr(@$_SERVER['PATH_INFO'], 1));

... для получения массива разделенных символом значений в URI после имени файла.

Пример. Предположим, что в вашем приложении есть файл API api.php, и вы делаете запрос для api.php/members/3, тогда $apiArgArray будет массивом, содержащим ['members', '3']. Затем вы можете использовать эти значения для запроса своей базы данных или выполнения другой обработки.

(2) Как создать объекты JSON для возврата в качестве ответа?

Вы можете взять любой объект PHP и превратить его в JSON с json_encode. Вы также захотите установить соответствующий заголовок.

header('Content-Type: application/json');
$myObject = (object) array( 'property' => 'value' ); // example
echo json_encode($myObject); // outputs JSON text

Все это полезно для API, который возвращает JSON, но следующий вопрос, который вы должны задать, это:

(3) Как сделать мой API RESTful?

Для этого мы будем использовать $_SERVER['REQUEST_METHOD'] для получения используемого метода, а затем на основе этого будем делать разные вещи. Итак, конечный результат - это что-то вроде...

header('Content-Type: application/json');
$apiArgArray = explode("/", substr(@$_SERVER['PATH_INFO'], 1));
$returnObject = (object) array();
/* Based on the method, use the arguments to figure out
   whether you're working with an individual or a collection, 
   then do your processing, and ultimately set $returnObject */
switch ($_SERVER['REQUEST_METHOD']) {
  case 'GET':
    // List entire collection or retrieve individual member
    break;
  case 'PUT':       
    // Replace entire collection or member
    break;  
  case 'POST':      
    // Create new member
    break;
  case 'DELETE':    
    // Delete collection or member
    break;
}
echo json_encode($returnObject);

Источники: https://stackoverflow.com/questions/359047/detecting-request-type-in-php-get-post-put-or-delete и http://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_web_services

3

Я знаю, что этот вопрос принят и немного возраст, но это может быть полезно для некоторых людей, которые все еще считают это актуальным. Хотя результат не является полным RESTful API, API Builder mini lib для PHP позволяет легко преобразовывать базы данных MySQL в доступные API JSON, доступные в Интернете.

3

Еще одна структура, которая до сих пор не упоминалась, Laravel. Это отлично подходит для создания PHP-приложений в целом, но благодаря большому маршрутизатору он действительно удобен и прост в создании богатых API-интерфейсов. Возможно, это не так тонко, как Slim или Sliex, но это дает вам прочную структуру.

Смотрите Аарон Кужемчак - Простая разработка API с Laravel на YouTube и

Laravel 4: запуск в RESTful API на NetTuts +

0

Как сказал simon marc, этот процесс почти такой же, как и для вас или я просматриваю веб-сайт. Если вам удобнее использовать фреймворк Zend, есть несколько простых советов по использованию, которые облегчают жизнь. Самая сложная часть создания успокоительного api - это его дизайн и делает его действительно спокойным, думайте CRUD в терминах базы данных.

Возможно, вам действительно нужен интерфейс xmlrpc или что-то еще подобное. Что вы хотите, чтобы этот интерфейс позволял вам делать?

- EDIT

Вот где я начал с приятных api и Zend Framework. Пример Zend Framework

Короче говоря, не используйте сервер отдыха Zend, он устарел.

  • 0
    Как вы используете Zend Framework для создания RESTful API?
  • 0
    Если вам интересно, я напишу в своем блоге кое-что о начале работы с веб-сервисами ZF и RESTful с полным рабочим примером.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню