Как создать спокойный API?
Проблема заключается в следующем:
У меня есть веб-приложение, которое работает на PHP-сервере. Я бы хотел создать для него api REST.
Я провел некоторое исследование и выяснил, что REST api использует методы HTTP (GET, POST...) для определенных URI с ключом аутентификации (не обязательно), и информация возвращается в виде HTTP-ответа с информацией в виде XML или JSON (я бы предпочел JSON).
Мой вопрос таков:
- Как мне, как разработчику приложения, создать эти URI? Нужно ли мне это написать PHP-код по этому URI?
- Как мне создать объекты JSON для возврата в качестве ответа?
7 answers
Вот очень простой пример на простом php.
Есть 2 файла client.php & api.php . Я поместил оба файла на один и тот же URL: http://localhost:8888/
, поэтому вам придется изменить ссылку на свой собственный URL. (файл может находиться на двух разных серверах).
Это всего лишь пример, он очень быстрый и грязный, к тому же прошло много времени с тех пор, как я занимался php. Но в этом и заключается идея 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));
?>
Я не обращался к базе данных для этого примера, но обычно это то, что вы должны делать. Вы также должны заменить функцию "file_get_contents" на "curl".
В 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();
Это почти то же самое, что создать обычный веб-сайт.
Обычный шаблон для веб-сайта 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 работает только с вызовом get, я думаю, что это можно сделать просто (для проверки я обычно использую curl).
$info = file_get_contents(url);
$info = json_decode($info);
Но чаще всего для выполнения вызовов get и post используется библиотека curl. Вы можете спросить меня, нужна ли вам помощь с керлом.
Один раз чтобы получить информацию из api, вы можете выполнить 4 и 5 шагов.
Посмотрите документ php для функции json и file_get_contents.
Завиток: http://fr.php.net/manual/fr/ref.curl.php
РЕДАКТИРОВАТЬ
Нет, подожди, я не понимаю. "страница php API" что вы имеете в виду под этим?
Api - это только создание/восстановление вашего проекта. Вы НИКОГДА не отправляете напрямую результат html (если вы создаете веб-сайт) через api. Вы вызываете api с URL-адресом, api возвращаемая информация, вы используете эту информацию для создания конечного результата.
Пример: вы хотите написать html-страницу, которая скажет привет ххх. Но чтобы получить имя пользователя, вам нужно получить информацию из api.
Итак, предположим, что в вашем api есть функция, у которой в качестве аргумента есть идентификатор пользователя и которая возвращает имя этого пользователя (скажем, getUserNameById(идентификатор пользователя)), и вы вызываете эту функцию только по URL-адресу, такому как ваш/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.
}
Со стороны клиента вы сделай
$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.
Это понятнее?
(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 спокойным?
Для этого мы будем использовать $_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/a/897311/1766230 и http://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_web_services
Еще одна структура, которая до сих пор не упоминалась, - это Laravel. Он отлично подходит для создания PHP-приложений в целом, но благодаря отличному маршрутизатору действительно удобно и просто создавать богатые API. Возможно, он не такой тонкий, как Slim или Sliex, но он дает вам прочную структуру.
Смотрите Аарон Куземчак - Простая разработка API С Laravel на YouTube и
Laravel 4: Начало работы с RESTful API на NetTuts+
Я знаю, что этот вопрос принят и имеет некоторый возраст, но это может быть полезно для некоторых людей, которые все еще считают его актуальным. Хотя результатом не является полный API RESTful, мини-библиотека API Builder для PHP позволяет легко преобразовывать базы данных MySQL в доступные через Интернет API JSON.
Как сказал Саймон Марк, процесс во многом такой же, как и для вас или меня, просматривающих веб-сайт. Если вам удобно использовать Zend framework, есть несколько простых в использовании руководств, которые облегчают настройку. Самая сложная часть создания restful api - это разработка ИТ-интерфейса и создание его по-настоящему спокойного, подумайте о грубости в терминах базы данных.
Возможно, вам действительно нужен интерфейс xmlrpc или что-то еще подобное. Для чего вам нужен этот интерфейс позволить вам это сделать?
--РЕДАКТИРОВАТЬ
Вот где я начал работать с restful api и Zend Framework. Пример платформы Zend
Короче говоря, не используйте сервер Zend rest, он устарел.