Статьи

Создание API-ориентированного веб-приложения

Планируете начать работу над новым веб-приложением? В этом руководстве мы обсудим, как создать веб-приложение, ориентированное на API, и объясним, почему это важно в современном многоплатформенном мире.

Если вам нужно быстрое решение, ознакомьтесь с одним из элементов API в Envato Market, например API Framework , который позволяет вам создать собственный API в кратчайшие сроки. Фреймворк очень прост в использовании и расширяется, если у вас есть знания PHP и ООП.

API Framework
API Framework

Или вы можете попробовать Any API для HTML с сервисом PHP на Envato Studio. Если вы заказываете эту услугу, вы можете анализировать любой API со сторонних веб-сайтов и показывать результаты на своем веб-сайте с вашим макетом и функциями.

Для тех, кто не знаком с этим термином, API — это сокращение от Application Programming Interface . Согласно Википедии :

Интерфейс прикладного программирования (API) — это спецификация на основе исходного кода, предназначенная для использования компонентами программного обеспечения в качестве интерфейса для связи друг с другом. API может включать спецификации для подпрограмм, структур данных, классов объектов и переменных.

Проще говоря, API относится к набору функций, встроенных в приложение, которые могут использоваться другими приложениями (или сами по себе, как мы увидим позже) для взаимодействия с приложением. API — это отличный способ безопасного и надежного предоставления функциональных возможностей приложения внешним приложениям, поскольку все функциональные возможности, которые могут выполнять эти внешние приложения, ограничены возможностями, предоставляемыми в API.

API-ориентированное веб-приложение — это веб-приложение, которое в основном выполняет большинство своих функций, если нет, через API-вызовы.

API-ориентированное веб-приложение — это веб-приложение, которое в основном выполняет большинство своих функций, если нет, через API-вызовы. Например, если вы войдете в систему пользователя, вы отправите его учетные данные в API, и API вернет вам результат, сообщив, если пользователь предоставил правильную комбинацию пароля пользователя.

Другой характеристикой API-ориентированного веб-приложения является то, что API всегда будет без сохранения состояния, то есть он не сможет распознавать вызовы API по сеансам. Поскольку вызовы API обычно выполняются через код бэкэнда, будет сложно реализовать обработку сеанса, поскольку в этом обычно нет файлов cookie. Это ограничение действительно хорошо — это «заставляет» разработчика создавать API, который работает не на основе состояния текущего пользователя, а скорее на функциональности, которая, в свою очередь, облегчает тестирование, поскольку текущее состояние пользователя не нужно воссоздавать.

Как веб-разработчики, мы видели, как технологии развиваются из первых рук. Общеизвестно, что сегодня люди используют приложения не только через браузер, но и через другие гаджеты, такие как мобильные телефоны и планшеты. Например, в этой статье на Mashable, озаглавленной «Потребители теперь тратят больше времени на мобильные приложения, чем в Интернете» , говорится:

В новом отчете утверждается, что потребители тратят больше времени на мобильные приложения, чем на Интернет.

Flurry сравнил свои мобильные данные со статистикой comScore и Alexa и обнаружил, что в июне потребители тратили 81 минуту в день, используя мобильные приложения, по сравнению с 74 минутами веб-серфинга.

Вот более свежая статья от ReadWriteWeb, озаглавленная «Больше людей ищут на мобильных устройствах, чем используют IE6 и IE7 вместе взятые :

Последние данные о тенденциях браузеров от Sitepoint показывают, что больше людей просматривают Интернет на смартфонах, чем используют Internet Explorer 6 и 7 вместе взятые. Эти два старых клоунара годами были предметом ошибок веб-разработчиков, требуя, чтобы сайты как можно лучше деградировали до этого наименее распространенного знаменателя браузеров. Но теперь это новый мир; 6,95% веб-активности в ноябре 2011 года было в мобильных браузерах, и только 6,49% — в IE 6 или 7.

Как мы можем ясно видеть, все больше и больше людей получают новости из альтернативных мест, в частности с мобильных устройств.

Это неизбежно приведет к большему использованию нашего приложения, поскольку оно может использоваться везде, где хочет человек.

Одним из основных преимуществ создания приложения, ориентированного на API, является то, что оно помогает создавать функциональные возможности, которые могут использоваться ЛЮБЫМ устройством, будь то браузер, мобильный телефон, планшет или даже настольное приложение. Все, что вам нужно сделать, это создать API таким образом, чтобы все эти устройства могли общаться с ним, и вуаля! Вы создадите централизованное приложение, которое может принимать и выполнять функции с любого устройства, которое есть у человека!

API-ориентированная прикладная диаграмма

API-ориентированная прикладная диаграмма

Создавая приложение таким образом, мы можем легко использовать преимущества различных средств, используемых разными людьми. Это неизбежно приведет к большему использованию приложения, поскольку оно может использоваться везде, где хочет человек.

Чтобы прояснить ситуацию, вот статья о новом переработанном веб-сайте Twitter , который рассказывает нам о том, как они теперь используют свой API для питания Twitter.com, по сути делая его API-ориентированным:

Одним из наиболее важных архитектурных изменений является то, что Twitter.com теперь является клиентом нашего собственного API. Он извлекает данные с тех же конечных точек, что и мобильный сайт, наши приложения для iPhone, iPad, Android и все сторонние приложения. Этот сдвиг позволил нам выделить больше ресурсов для команды API, создав более 40 патчей. При начальной загрузке страницы и каждом вызове от клиента все данные теперь выбираются из высокооптимизированного фрагмента JSON-кэша.

В этом руководстве мы создадим простое приложение со списком TODO, ориентированное на API, и создадим в браузере одного клиентского интерфейса, который взаимодействует с нашим приложением со списком TODO. В итоге вы узнаете неотъемлемые части приложения, ориентированного на API, и в то же время узнаете, как обеспечить безопасную связь между ними. Имея это в виду, давайте начнем!


Приложение TODO, которое мы будем создавать в этом руководстве, будет иметь основные функции CRUD:

  • Создать элементы TODO
  • Читать ТОДО
  • Обновить элементы TODO (переименовать, пометить как выполненное, пометить как отмененное)
  • Удалить элементы TODO

Каждый предмет TODO будет иметь:

  • Название
  • Дата исполнения
  • Описание
  • флаг, указывающий, выполнен ли элемент TODO
  • Давайте также макетируем приложение, чтобы у нас было руководство о том, как оно должно выглядеть потом:

    SimpleTODO Mockup

    SimpleTODO Mockup


    Поскольку мы разрабатываем приложение, ориентированное на API, мы будем создавать два «проекта»: сервер API и клиент переднего плана . Начнем с создания сервера API.

    В папке вашего веб-сервера создайте папку с именем simpletodo_api и создайте файл index.php . Этот файл index.php будет выступать в качестве фронт-контроллера для API, поэтому все запросы к серверу API будут выполняться через этот файл. Откройте его и поместите в него следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
// Define path to data folder
define(‘DATA_PATH’, realpath(dirname(__FILE__).’/data’));
 
//include our models
include_once ‘models/TodoItem.php’;
 
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
try {
    //get all of the parameters in the POST/GET request
    $params = $_REQUEST;
     
    //get the controller and format it correctly so the first
    //letter is always capitalized
    $controller = ucfirst(strtolower($params[‘controller’]));
     
    //get the action and format it correctly so all the
    //letters are not capitalized, and append ‘Action’
    $action = strtolower($params[‘action’]).’Action’;
 
    //check if the controller exists.
    if( file_exists(«controllers/{$controller}.php») ) {
        include_once «controllers/{$controller}.php»;
    } else {
        throw new Exception(‘Controller is invalid.’);
    }
     
    //create a new instance of the controller, and pass
    //it the parameters from the request
    $controller = new $controller($params);
     
    //check if the action exists in the controller.
    if( method_exists($controller, $action) === false ) {
        throw new Exception(‘Action is invalid.’);
    }
     
    //execute the action
    $result[‘data’] = $controller->$action();
    $result[‘success’] = true;
     
} catch( Exception $e ) {
    //catch any exceptions and report the problem
    $result = array();
    $result[‘success’] = false;
    $result[‘errormsg’] = $e->getMessage();
}
 
//echo the result of the API call
echo json_encode($result);
exit();

По сути, мы создали простой фронт-контроллер, который выполняет следующие действия:

  • Примите вызов API с любым количеством параметров
  • Извлеките Controller и Action для вызова API
  • Выполните необходимые проверки, чтобы убедиться, что Controller и Action существуют
  • Выполнить вызов API
  • Поймать ошибки, если таковые имеются
  • Отправить результат вызывающему

Помимо файла index.php , создайте три папки: контроллеры , модели и папку данных .

Папки сервера API
  • Папка controllers будет содержать все контроллеры, которые мы будем использовать для сервера API. Мы будем строить его с использованием архитектуры MVC, чтобы сделать структуру сервера API более чистой и организованной.
  • Папка моделей будет содержать все модели данных для сервера API.
  • Папка данных будет где сервер API сохраняет любые данные

Перейдите в папку контроллеров и создайте файл с именем Todo.php . Это будет наш контроллер для любых задач, связанных со списком TODO. Имея в виду функции, которые нам понадобятся для нашего приложения TODO, создайте необходимые методы для контроллера Todo:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
class Todo
{
    private $_params;
     
    public function __construct($params)
    {
        $this->_params = $params;
    }
     
    public function createAction()
    {
        //create a new todo item
    }
     
    public function readAction()
    {
        //read all the todo items
    }
     
    public function updateAction()
    {
        //update a todo item
    }
     
    public function deleteAction()
    {
        //delete a todo item
    }
}

Теперь добавьте необходимый функционал к каждому action . Я предоставлю код для метода createAction и оставлю на createAction создание кода для других методов. Если вы не в настроении, вы можете просто загрузить исходный код для демонстрации и скопировать его оттуда.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public function createAction()
{
    //create a new todo item
    $todo = new TodoItem();
    $todo->title = $this->_params[‘title’];
    $todo->description = $this->_params[‘description’];
    $todo->due_date = $this->_params[‘due_date’];
    $todo->is_done = ‘false’;
     
    //pass the user’s username and password to authenticate the user
    $todo->save($this->_params[‘username’], $this->_params[‘userpass’]);
     
    //return the todo item in array format
    return $todo->toArray();
}

Создайте TodoItem.php внутри папки models чтобы мы могли создать код «создания предмета». Обратите внимание, что я не буду подключаться к базе данных, скорее, я буду сохранять информацию в файлы. Хотя это должно быть относительно легко сделать эту работу с любой базой данных.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
class TodoItem
{
    public $todo_id;
    public $title;
    public $description;
    public $due_date;
    public $is_done;
     
    public function save($username, $userpass)
    {
        //get the username/password hash
        $userhash = sha1(«{$username}_{$userpass}»);
        if( is_dir(DATA_PATH.»/{$userhash}») === false ) {
            mkdir(DATA_PATH.»/{$userhash}»);
        }
         
        //if the $todo_id isn’t set yet, it means we need to create a new todo item
        if( is_null($this->todo_id) || !is_numeric($this->todo_id) ) {
            //the todo id is the current time
            $this->todo_id = time();
        }
         
        //get the array version of this todo item
        $todo_item_array = $this->toArray();
         
        //save the serialized array version into a file
        $success = file_put_contents(DATA_PATH.»/{$userhash}/{$this->todo_id}.txt», serialize($todo_item_array));
         
        //if saving was not successful, throw an exception
        if( $success === false ) {
            throw new Exception(‘Failed to save todo item’);
        }
         
        //return the array version
        return $todo_item_array;
    }
     
    public function toArray()
    {
        //return an array version of the todo item
        return array(
            ‘todo_id’ => $this->todo_id,
            ‘title’ => $this->title,
            ‘description’ => $this->description,
            ‘due_date’ => $this->due_date,
            ‘is_done’ => $this->is_done
        );
    }
}

Метод createAction вызывает две функции в модели TodoItem :

  • save () — это сохраняет TodoItem в файл, а также при необходимости устанавливает todo_id для TodoItem
  • toArray () — возвращает версию массива TodoItem , где переменные являются индексами массива

Поскольку API вызывается через HTTP-запросы, давайте проверим этот API-вызов, вызвав его через браузер:

HTTP: // локальный / simpletodo_api / контроллер = TODO и действие = создать и заголовок = тест% 20title и описание = тест% 20description & due_date = 12/08/2011 и имя пользователя = Никко & UserPass = test1234

Если все работает, вы должны увидеть новую папку внутри папки data , а внутри этой папки вы должны увидеть файл со следующим содержимым:

результат createAction

createAction()

Поздравляем! Вы успешно создали сервер API и сделали вызов API!


В настоящее время сервер API настроен на прием ВСЕХ запросов API. Нам нужно ограничить это только нашими собственными приложениями, чтобы гарантировать, что только наши собственные клиентские клиенты могут делать запросы API. В качестве альтернативы вы можете создать систему, в которой пользователи могут создавать свои собственные приложения, имеющие доступ к вашему API-серверу, аналогично тому, как работают приложения Facebook и Twitter.

Начните с создания набора пар id-ключ для клиентов, которые будут использовать сервер API. Поскольку это всего лишь демонстрация, мы можем использовать любую произвольную строку из 32 символов. Для APP ID , скажем, приложение APP001 .

Снова откройте файл index.php и обновите его следующим кодом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
// Define path to data folder
define(‘DATA_PATH’, realpath(dirname(__FILE__).’/data’));
 
//Define our id-key pairs
$applications = array(
    ‘APP001′ => ’28e336ac6c9423d946ba02d19c6a2632’, //randomly generated app key
);
//include our models
include_once ‘models/TodoItem.php’;
 
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
try {
    //*UPDATED*
    //get the encrypted request
    $enc_request = $_REQUEST[‘enc_request’];
     
    //get the provided app id
    $app_id = $_REQUEST[‘app_id’];
     
    //check first if the app id exists in the list of applications
    if( !isset($applications[$app_id]) ) {
        throw new Exception(‘Application does not exist!’);
    }
     
    //decrypt the request
    $params = json_decode(trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $applications[$app_id], base64_decode($enc_request), MCRYPT_MODE_ECB)));
     
    //check if the request is valid by checking if it’s an array and looking for the controller and action
    if( $params == false || isset($params->controller) == false || isset($params->action) == false ) {
        throw new Exception(‘Request is not valid’);
    }
     
    //cast it into an array
    $params = (array) $params;
    …
    …
    …

На самом деле мы реализовали очень простой способ аутентификации наших интерфейсных клиентов с использованием системы, аналогичной аутентификации с использованием открытого и закрытого ключей. В основном, здесь пошаговая разбивка того, как происходит аутентификация:

Шифрование с открытым ключом

Шифрование с открытым ключом

  • сделан вызов API, в нем предусмотрены $ app_id и $ enc_request .
  • значение $ enc_request — это параметры вызова API, зашифрованные с использованием ключа APP KEY . APP KEY НИКОГДА не отправляется на сервер, он используется только для хэширования запроса. Кроме того, запрос может быть расшифрован только с помощью APP KEY .
  • как только вызов API поступит на сервер API, он проверит свой список приложений на предмет предоставленного APP ID
  • при обнаружении сервер API пытается расшифровать запрос с помощью ключа, соответствующего отправленному APP ID
  • если он успешно расшифровывался, продолжайте с программой

Теперь, когда сервер API защищен с помощью APP ID и APP SECRET , мы можем начать программирование клиентского интерфейса для использования сервера API.


Мы начнем с настройки новой папки для клиентского интерфейса. Создайте папку с именем simpletodo_client_browser в папке вашего веб-сервера. Когда это будет сделано, создайте файл index.php и поместите этот код внутри:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html>
<head>
    <title>SimpleTODO</title>
     
    <link rel=»stylesheet» href=»css/reset.css» type=»text/css» />
    <link rel=»stylesheet» href=»css/bootstrap.min.css» type=»text/css» />
     
    <script src=»js/jquery.min.js»></script>
    <script src=»js/jquery-ui-1.8.16.custom.min.js»></script>
     
    <style>
    body {
        padding-top: 40px;
    }
    #main {
        margin-top: 80px;
        text-align: center;
    }
    </style>
</head>
<body>
    <div class=»topbar»>
        <div class=»fill»>
            <div class=»container»>
                <a class=»brand» href=»index.php»>SimpleTODO</a>
            </div>
        </div>
    </div>
    <div id=»main» class=»container»>
        <form class=»form-stacked» method=»POST» action=»login.php»>
            <div class=»row»>
                <div class=»span5 offset5″>
                    <label for=»login_username»>Username:</label>
                    <input type=»text» id=»login_username» name=»login_username» placeholder=»username» />
                 
                    <label for=»login_password»>Password:</label>
                    <input type=»password» id=»login_password» name=»login_password» placeholder=»password» />
                     
                </div>
            </div>
            <div class=»actions»>
                <button type=»submit» name=»login_submit» class=»btn primary large»>Login or Register</button>
            </div>
        </form>
    </div>
</body>
</html>

Это должно выглядеть примерно так:

Страница входа в SimpleTODO

Страница входа в SimpleTODO

Обратите внимание, что я включил 2 файла JavaScript и 2 файла CSS здесь:

Далее, давайте создадим файл login.php чтобы сохранить имя пользователя и пароль в сеансе на клиенте.

01
02
03
04
05
06
07
08
09
10
11
<?php
//get the form values
$username = $_POST[‘login_username’];
$userpass = $_POST[‘login_password’];
 
 
session_start();
$_SESSION[‘username’] = $username;
$_SESSION[‘userpass’] = $userpass;
header(‘Location: todo.php’);
exit();

Здесь мы просто запускаем сеанс для пользователя, основываясь на комбинации имени пользователя и пароля, которую предоставит пользователь. Это действует как простой комбинированный ключ, который позволяет пользователю получить доступ к сохраненным элементам TODO для конкретной комбинации имени пользователя и пароля. Затем мы перенаправляем на todo.php , где начинаем взаимодействовать с сервером API. Прежде чем мы начнем кодировать файл todo.php , давайте сначала создадим класс ApiCaller , который будет инкапсулировать все необходимые методы вызова API, включая шифрование запросов.

Создайте apicaller.php и поместите в него следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
class ApiCaller
{
    //some variables for the object
    private $_app_id;
    private $_app_key;
    private $_api_url;
     
    //construct an ApiCaller object, taking an
    //APP ID, APP KEY and API URL parameter
    public function __construct($app_id, $app_key, $api_url)
    {
        $this->_app_id = $app_id;
        $this->_app_key = $app_key;
        $this->_api_url = $api_url;
    }
     
    //send the request to the API server
    //also encrypts the request, then checks
    //if the results are valid
    public function sendRequest($request_params)
    {
        //encrypt the request parameters
        $enc_request = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->_app_key, json_encode($request_params), MCRYPT_MODE_ECB));
         
        //create the params array, which will
        //be the POST parameters
        $params = array();
        $params[‘enc_request’] = $enc_request;
        $params[‘app_id’] = $this->_app_id;
         
        //initialize and setup the curl handler
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->_api_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, count($params));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
 
        //execute the request
        $result = curl_exec($ch);
         
        //json_decode the result
        $result = @json_decode($result);
         
        //check if we’re able to json_decode the result correctly
        if( $result == false || isset($result[‘success’]) == false ) {
            throw new Exception(‘Request was not correct’);
        }
         
        //if there was an error in the request, throw an exception
        if( $result[‘success’] == false ) {
            throw new Exception($result[‘errormsg’]);
        }
         
        //if everything went great, return the data
        return $result[‘data’];
    }
}

Мы будем использовать класс ApiCaller для отправки запросов на наш сервер API. Таким образом, все необходимое шифрование и код инициализации cURL будут в одном месте, и нам не придется повторять наш код.

  • функция __construct принимает три параметра:

    1. $ app_idAPP ID для клиента ( APP001 для клиента браузера)
    2. $ app_keyключ приложения для клиента ( 28e336ac6c9423d946ba02d19c6a2632 для клиента браузера)
    3. $ api_url — URL-адрес сервера API, который является http://localhost/simpletodo_api/
  • sendRequest() :

    1. шифрует параметры запроса с использованием библиотеки mcrypt таким же образом, как его расшифровывает сервер API
    2. генерирует параметры $_POST для отправки на сервер API
    3. выполняет вызов API через cURL
    4. проверяет результат вызова API успешно или нет
    5. возвращает данные, когда все прошло по плану

Теперь давайте начнем со страницы todo.php . Прежде всего, давайте создадим некоторый код для извлечения текущего списка элементов nikko для пользователя nikko с паролем test1234 (это комбинация пользователя и пароля, которую мы использовали ранее для тестирования сервера API).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
session_start();
include_once ‘apicaller.php’;
 
$apicaller = new ApiCaller(‘APP001′, ’28e336ac6c9423d946ba02d19c6a2632’, ‘http://localhost/simpletodo_api/’);
 
$todo_items = $apicaller->sendRequest(array(
    ‘controller’ => ‘todo’,
    ‘action’ => ‘read’,
    ‘username’ => $_SESSION[‘username’],
    ‘userpass’ => $_SESSION[‘userpass’]
));
 
echo »;
var_dump($todo_items);

Перейдите на страницу index.php , войдите как nikko / test1234 , и вы должны увидеть var_dump() элемента TODO, который мы создали ранее.

TODO item var_dump

Поздравляем, вы успешно сделали вызов API на сервере API! В этом коде мы имеем:

  • начал сеанс, поэтому у нас есть доступ к имени username и userpass в $_SESSION
  • создать новый класс ApiCaller , присвоив ему APP ID , APP KEY и URL-адрес сервера API
  • отправить запрос через метод sendRequest()

Теперь давайте переформатируем данные, чтобы они выглядели лучше. Добавьте следующий HTML-код в код todo.php . Не забудьте удалить var_dump() !

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
<!DOCTYPE html>
<html>
<head>
    <title>SimpleTODO</title>
     
    <link rel=»stylesheet» href=»css/reset.css» type=»text/css» />
    <link rel=»stylesheet» href=»css/bootstrap.min.css» type=»text/css» />
    <link rel=»stylesheet» href=»css/flick/jquery-ui-1.8.16.custom.css» type=»text/css» />
     
    <script src=»js/jquery.min.js»></script>
    <script src=»js/jquery-ui-1.8.16.custom.min.js»></script>
     
    <style>
    body {
        padding-top: 40px;
    }
    #main {
        margin-top: 80px;
    }
     
    .textalignright {
        text-align: right;
    }
     
    .marginbottom10 {
        margin-bottom: 10px;
    }
    #newtodo_window {
        text-align: left;
        display: none;
    }
    </style>
     
    <script>
    $(document).ready(function() {
        $(«#todolist»).accordion({
            collapsible: true
        });
        $(«.datepicker»).datepicker();
        $(‘#newtodo_window’).dialog({
            autoOpen: false,
            height: ‘auto’,
            width: ‘auto’,
            modal: true
        });
        $(‘#newtodo’).click(function() {
            $(‘#newtodo_window’).dialog(‘open’);
        });
    });
    </script>
</head>
<body>
    <div class=»topbar»>
        <div class=»fill»>
            <div class=»container»>
                <a class=»brand» href=»index.php»>SimpleTODO</a>
            </div>
        </div>
    </div>
    <div id=»main» class=»container»>
        <div class=»textalignright marginbottom10″>
            <span id=»newtodo» class=»btn info»>Create a new TODO item
            <div id=»newtodo_window» title=»Create a new TODO item»>
                <form method=»POST» action=»new_todo.php»>
                    <p>Title:<br /><input type=»text» class=»title» name=»title» placeholder=»TODO title» /></p>
                    <p>Date Due:<br /><input type=»text» class=»datepicker» name=»due_date» placeholder=»MM/DD/YYYY» /></p>
                    <p>Description:<br /><textarea class=»description» name=»description»></textarea></p>
                    <div class=»actions»>
                        <input type=»submit» value=»Create» name=»new_submit» class=»btn primary» />
                    </div>
                </form>
            </div>
        </div>
        <div id=»todolist»>
            <?php foreach($todo_items as $todo): ?>
            <h3><a href=»#»><?php echo $todo->title;
            <div>
                <form method=»POST» action=»update_todo.php»>
                <div class=»textalignright»>
                    <a href=»delete_todo.php?todo_id=<?php echo $todo->todo_id; ?>»>Delete</a>
                </div>
                <div>
                    <p>Date Due:<br /><input type=»text» id=»datepicker_<?php echo $todo->todo_id; ?>» class=»datepicker» name=»due_date» value=»12/09/2011″ /></p>
                    <p>Description:<br /><textarea class=»span8″ id=»description_<?php echo $todo->todo_id; ?>» class=»description» name=»description»><?php echo $todo->description;
                </div>
                <div class=»textalignright»>
                    <?php if( $todo->is_done == ‘false’ ): ?>
                    <input type=»hidden» value=»false» name=»is_done» />
                    <input type=»submit» class=»btn» value=»Mark as Done?»
                    <?php else: ?>
                    <input type=»hidden» value=»true» name=»is_done» />
                    <input type=»button» class=»btn success» value=»Done!»
                    <?php endif;
                    <input type=»hidden» value=»<?php echo $todo->todo_id; ?>» name=»todo_id» />
                    <input type=»hidden» value=»<?php echo $todo->title; ?>» name=»title» />
                    <input type=»submit» class=»btn primary» value=»Save Changes» name=»update_button» />
                </div>
                </form>
            </div>
            <?php endforeach;
        </div>
    </div>
</body>
</html>

Теперь это должно выглядеть примерно так:

ТОДО Главная

Довольно круто, да? Но это в настоящее время ничего не делает, поэтому давайте начнем добавлять некоторые функциональные возможности. Я предоставлю код для new_todo.php , который будет вызывать вызов API todo/create для создания нового элемента TODO. Создание других страниц ( update_todo.php и delete_todo.php ) должно быть очень похоже на эту, поэтому я оставлю это на ваше delete_todo.php чтобы создать их. Откройте new_todo.php и добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<?php
session_start();
include_once ‘apicaller.php’;
 
$apicaller = new ApiCaller(‘APP001′, ’28e336ac6c9423d946ba02d19c6a2632’, ‘http://localhost/simpletodo_api/’);
 
$new_item = $apicaller->sendRequest(array(
    ‘controller’ => ‘todo’,
    ‘action’ => ‘create’,
    ‘title’ => $_POST[‘title’],
    ‘due_date’ => $_POST[‘due_date’],
    ‘description’ => $_POST[‘description’],
    ‘username’ => $_SESSION[‘username’],
    ‘userpass’ => $_SESSION[‘userpass’]
));
 
header(‘Location: todo.php’);
exit();
?>

Как видите, страница ApiCaller снова использует ApiCaller чтобы упростить отправку запроса todo / create на сервер API. Это в основном то же самое, что и раньше:

  • начать сеанс, чтобы иметь доступ к $username и $userpass сохраненным в $_SESSION
  • создать новый класс ApiCaller , присвоив ему APP ID , APP KEY и URL-адрес сервера API
  • отправить запрос через метод sendRequest()
  • перенаправить обратно на todo.php
Новый ТОДО

Поздравляю, это работает! Вы успешно создали приложение, ориентированное на API!


Есть так много преимуществ для разработки приложения, основанного на API. Хотите создать Android-версию приложения SimpleTODO? Вся необходимая вам функциональность уже есть на сервере API, поэтому все, что вам нужно сделать, это просто создать клиент! Хотите провести рефакторинг или оптимизировать некоторые классы? Нет проблем — просто убедитесь, что результат одинаков. Нужно добавить больше функциональности? Вы можете сделать это без влияния на любой код клиента!

Хотя существуют некоторые недостатки, такие как более длительное время разработки или более сложная задача, преимущества разработки веб-приложения таким образом значительно перевешивают недостатки. Это зависит от нас, чтобы использовать этот вид развития сегодня, чтобы мы могли пожинать плоды позже.

Планируете ли вы использовать сервер API для вашего следующего веб-приложения или уже использовали ту же технику для проекта в прошлом? Дай мне знать в комментариях!