Статьи

Работа с сервисами RESTful в CodeIgniter

CodeIgniter становится широко известным благодаря своей мощной среде разработки веб-приложений на основе PHP, но не часто мы видим примеры его использования для чего-либо еще. Сегодня мы узнаем, как мы можем использовать CodeIgniter для создания API RESTful для ваших существующих веб-приложений, и продемонстрируем, как взаимодействовать с вашим собственным API или другими веб-сервисами RESTful, такими как Facebook и Twitter.

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

Если вы следили за серией CodeIgniter From Scratch, вы уже знаете, что относительно быстро и легко собрать простые веб-приложения, такие как блоги, системы CMS, сайты с брошюрами и т. Д. Одна вещь, о которой вы, возможно, и не задумывались, это используя CodeIgniter для создания интерактивного API. Попробовав несколько существующих реализаций REST, я обнаружил, что им не только не хватает простоты, но и отсутствуют большинство функций, которые можно ожидать от реализации RESTful; поэтому я построил свой. Из этого туториала вы узнаете, как использовать этот код для настройки REST API, и приведете пример взаимодействия с ним из вашего веб-приложения.

  1. У вас есть веб-сервер, настроенный локально или онлайн, и вы знаете, как управлять файлами на нем.
  2. Вы прочитали несколько учебников CodeIgniter из Scratch .
  3. Вы знаете, как настроить CodeIgniter.
  4. Вы немного знаете об услугах RESTful.

Этот урок разбит на две части. Мы начнем с изучения того, как создать сервис RESTful, затем, далее, мы научимся взаимодействовать с ним несколькими различными способами.

Во-первых, вам нужно скачать код codeigniter-restserver с GitHub, распаковать его и перенести код на свой сервер.

Когда вы откроете папку, вы увидите полную установку CodeIgniter, которая служит для запуска демонстрации. Это позволяет людям поиграть с демо REST перед интеграцией с существующим приложением.

Откройте «application / config / config.php» и установите base_url, чтобы ссылки работали. Этот base_url будет отличаться для всех и полностью зависит от того, куда вы загрузили свои файлы.

После извлечения файлов и установки base_url мы готовы загрузить нашу установку RESTful CodeIgniter и взглянуть на прилагаемую демоверсию. Просмотрите базовый URL, который по умолчанию:

HTTP: // локальный / restserver

Здесь вы найдете несколько примеров ссылок на контроллер example_api , которые можно найти в «application / controllers / example_api.php» . Давайте разберем URL-адреса этих примеров, чтобы увидеть, что происходит. Первый URL очень простой.

Этот URL очень похож на любой другой URL CodeIgniter с контроллером и методом, но на этой диаграмме вы заметите, что метод называется «Ресурс». REST — это все о ресурсах, и они, по сути, являются существительными в вашем приложении, с которыми взаимодействуют (то есть добавляют, удаляют, редактируют, запрашивают) на основе заголовков HTTP и строк запроса URL или аргументов HTTP.

Формат вывода по умолчанию — XML, который мы видим в этом базовом примере. Другие ссылки немного больше и демонстрируют, как передавать параметры, и показывают, как можно изменить формат вывода в URL:

Обычно в CodeIgniter вы просто передаете значения параметров, но контроллер REST принимает любое количество параметров в любом порядке. Чтобы это работало, нам нужно передать имя параметра и значение в парах.

В конце URL-адреса находится параметр «format». Это зарезервированный параметр, который будет изменять формат вывода запрошенных данных следующим образом:

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

  • XML — почти любой язык программирования может читать XML
  • JSON — полезно для JavaScript и все более PHP-приложений.
  • CSV — открыть с помощью электронных таблиц
  • HTML — простая таблица HTML
  • php — представление PHP-кода, который может быть eval () ‘ed
  • serialize — сериализованные данные, которые могут быть не сериализованы в PHP

Хотя добавление формата в URL-адрес технически не является наиболее RESTful способом изменения форматов, оно позволяет легко тестировать браузер и позволяет разработчикам без cURL выполнять простые запросы GET к API. Более подходящим способом является отправка HTTP-заголовка Content-type на контроллер REST с использованием cURL, но это будет объяснено позже.

Теперь, если вы откроете application / controllers / example_api.php, вы сразу заметите несколько отличий от обычных контроллеров CodeIgniter.

В схеме MVC контроллер является центральной точкой логики. Он вызывается, когда пользователь делает запрос, а затем на основе логики в контроллере выбирает данные и выводит представления. CodeIgniter содержит свою собственную логику того, как должен работать контроллер, но поскольку мы делаем что-то другое, нам нужна наша собственная библиотека REST_Controller, которая содержит собственную логику, связанную с REST. Так что вместо того, чтобы просто использовать:

1
2
3
4
<?php
class Example_api extends Controller {
 
}

… вам нужно будет использовать:

1
2
3
4
5
6
<?php
require(APPPATH’.libraries/REST_Controller.php’);
 
class Example_api extends REST_Controller {
 
}

Теперь ваш пустой контроллер настроен, далее идут методы или «ресурсы». Вероятно, это самая запутанная часть руководства, если вы привыкли к тому, как работает CodeIgniter. По сути, вы берете Resource и HTTP-глагол и комбинируете их для создания имени метода. Таким образом, два примера, которые мы рассмотрели ранее, имели Ресурс пользователя и пользователей . Поскольку оба они были загружены в браузер, мы знаем, что он использовал запрос GET, и поэтому используются два метода ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
require(APPPATH’.libraries/REST_Controller.php’);
 
class Example_api extends REST_Controller {
 
    function user_get()
    {
        // respond with information about a user
    }
     
    function users_get()
    {
        // respond with information about several users
    }
}

Это может показаться немного странным, но это дает вам возможность использовать один и тот же URL-адрес и отвечать на запрос в зависимости от используемого глагола HTTP. Если кто-то попытается получить доступ к вашему API способом, который не разрешен (в данном примере это PUT или DELETE), он просто ответит 404. Если вы не уверены в глаголах HTTP, позвольте мне объяснить.

Используется для получения информации о существующем ресурсе. Это используется браузерами, когда вы вводите URL и нажимаете кнопку go, или когда вы нажимаете на ссылку, поэтому оно идеально подходит для извлечения информации на одном из ваших ресурсов REST (например, на пользователя).

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

Менее часто используемый и не поддерживаемый большинством браузеров, PUT используется для создания нового ресурса.

Также не используемый многими браузерами, этот HTTP-глагол довольно очевидно используется для удаления ресурса.

Если мы поместим это в код и позволим каждому глаголу для пользователя ресурса это будет выглядеть так:

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
<?php
require(APPPATH’.libraries/REST_Controller.php’);
 
class Example_api extends REST_Controller {
 
    function user_get()
    {
        // respond with information about a user
    }
 
    function user_put()
    {
        // create a new user and respond with a status/errors
    }
 
    function user_post()
    {
        // update an existing user and respond with a status/errors
    }
 
    function user_delete()
    {
        // delete a user and respond with a status/errors
    }
}

Итак, теперь API получил свою структуру, настроив ресурсы и определив метод для каждого HTTP-глагола, который мы хотим поддерживать; нам нужны параметры, чтобы мы могли использовать наши модели и библиотеки CodeIgniter. Это одно из основных преимуществ использования CodeIgniter для нашего 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
<?php
require(APPPATH’.libraries/REST_Controller.php’);
 
class Example_api extends REST_Controller {
 
    function user_get()
    {
        $data = array(‘returned: ‘. $this->get(‘id’));
        $this->response($data);
    }
     
    function user_post()
    {
        $data = array(‘returned: ‘. $this->post(‘id’));
        $this->response($data);
    }
 
    function user_put()
    {
        $data = array(‘returned: ‘. $this->put(‘id’));
        $this->response($data;
    }
 
    function user_delete()
    {
        $data = array(‘returned: ‘. $this->delete(‘id’));
        $this->response($data);
    }
}

Этот пример содержит пять новых частей кода:

Используется для возврата переменных GET либо из строки запроса, например, index.php / example_api / user? Id = 1, либо может быть задан более методом CodeIgniter с помощью index.php / example_api / user / id / 1.

Псевдоним для $ this-> input-> post (), который является методом CodeIgniter для доступа к переменным $ _POST с защитой XSS.

Читает в аргументах PUT, установленных в заголовках HTTP или через cURL.

Как вы уже догадались, это читает аргументы DELETE, также устанавливаемые в заголовках HTTP или через cURL.

Отправляет данные в браузер в любом формате, который был запрошен, или по умолчанию XML. При желании вы можете передать код состояния HTTP, чтобы показать, что он работает или не работает. Например, если указанный идентификатор отсутствует в базе данных, вы можете использовать $ this-> response (array (‘error’ => ‘User not found.’), 404);

До сих пор мы работали с примером API в чистой установке. Поэтому следующим шагом будет запуск API REST из существующей кодовой базы.

Хотя загрузка идет с полной установкой CodeIgniter для демонстрации и позволяет создавать API с нуля, важны только два файла:

  1. приложение / Config / rest.php
  2. Приложение / библиотеки / REST_Controller.php

Перетащите эти два файла в ваше приложение CodeIgniter и создайте новый контроллер 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
51
52
53
54
55
56
57
58
59
60
<?php
require(APPPATH.’/libraries/REST_Controller.php’);
 
class Api extends REST_Controller
{
    function user_get()
    {
        if(!$this->get(‘id’))
        {
            $this->response(NULL, 400);
        }
 
        $user = $this->user_model->get( $this->get(‘id’) );
         
        if($user)
        {
            $this->response($user, 200);
        }
 
        else
        {
            $this->response(NULL, 404);
        }
    }
     
    function user_post()
    {
        $result = $this->user_model->update( $this->post(‘id’), array(
            ‘name’ => $this->post(‘name’),
            ’email’ => $this->post(’email’)
        ));
         
        if($result === FALSE)
        {
            $this->response(array(‘status’ => ‘failed’));
        }
         
        else
        {
            $this->response(array(‘status’ => ‘success’));
        }
         
    }
     
    function users_get()
    {
        $users = $this->user_model->get_all();
         
        if($users)
        {
            $this->response($users, 200);
        }
 
        else
        {
            $this->response(NULL, 404);
        }
    }
}
?>

Здесь показан пример API с некоторыми общими именами моделей. В первом методе мы выбираем? Id = XX и передаем его в модель. Если данные найдены, мы отправляем их в функцию $ this-> response () со статусом 200. Если ничего не найдено, не возвращаем тело и 404, чтобы сказать, что ничего не найдено. Вы можете представить, как это можно расширить, чтобы запускать все виды действий API для вашего веб-приложения.

Теперь ваш API создан и нуждается в защите, поэтому только пользователи, которым предоставлен доступ, могут взаимодействовать с API. Чтобы установить тип входа, имена пользователей и пароли, откройте «application / config / rest.php» внутри вашей кодовой базы.

01
02
03
04
05
06
07
08
09
10
11
/*
|—————————————————————————
|
|—————————————————————————
|
|
|
|
|
*/
$config[‘rest_auth’] = ‘basic’;

Любой может взаимодействовать с любым из ваших контроллеров API.

Относительно небезопасный метод входа в систему, который следует использовать только во внутренних / защищенных сетях.

Гораздо более безопасный метод входа в систему, который шифрует имена пользователей и пароли. Если вы хотите иметь защищенный API, доступ к которому может получить кто угодно, используйте дайджест.

01
02
03
04
05
06
07
08
09
10
11
/*
|—————————————————————————
|
|—————————————————————————
|
|
|
|
|
*/
$config[‘rest_valid_logins’] = array(‘admin’ => ‘1234’);

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

Будь то API, который вы только что создали, или общедоступный сервис, такой как Twitter, вы захотите как-то взаимодействовать с ним. Поскольку службы RESTful работают с базовыми HTTP-запросами, это очень легко сделать несколькими различными способами.

Каждый из этих различных методов взаимодействия будет показан с кодом, размещенным непосредственно в методах Controller. Это просто для того, чтобы демки было проще для чтения и, как правило, для правильного разделения MVC их помещали бы в модель или библиотеку.

Используя очень простую PHP-функцию file_get_contents (), вы можете выполнить основной запрос GET. Это самый основной из всех методов, но стоит упомянуть о тех «быстрых и грязных» моментах.

1
2
3
4
5
$user = json_decode(
    file_get_contents(‘http://example.com/index.php/api/user/id/1/format/json’)
);
 
echo $user->name;

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

1
2
3
4
5
$user = json_decode(
    file_get_contents(‘http://admin:[email protected]/index.php/api/user/id/1/format/json’)
);
 
echo $user->name;

Есть несколько проблем с использованием этого метода: единственный способ установить дополнительные заголовки HTTP — это установить их вручную с помощью PHP-функции stream_context_create () , которая может быть очень сложной для разработчиков, плохо знакомых с внутренней работой HTTP-запросов. Другим недостатком является то, что вы получаете тело HTTP-ответа только в его необработанном формате, что означает, что вам нужно обрабатывать преобразование из одного запроса.

cURL — это самый гибкий способ взаимодействия с REST API, так как он был разработан именно для такого рода вещей. Вы можете установить заголовки HTTP, параметры HTTP и многое другое. Вот пример того, как обновить пользователя с помощью наших example_api и cURL, чтобы сделать запрос POST:

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
function native_curl($new_name, $new_email)
   {
       $username = ‘admin’;
       $password = ‘1234’;
        
       // Alternative JSON version
       // $url = ‘http://twitter.com/statuses/update.json’;
       // Set up and execute the curl process
       $curl_handle = curl_init();
       curl_setopt($curl_handle, CURLOPT_URL, ‘http://localhost/restserver/index.php/example_api/user/id/1/format/json’);
       curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($curl_handle, CURLOPT_POST, 1);
       curl_setopt($curl_handle, CURLOPT_POSTFIELDS, array(
           ‘name’ => $new_name,
           ’email’ => $new_email
       ));
        
       // Optional, delete this line if your API is open
       curl_setopt($curl_handle, CURLOPT_USERPWD, $username . ‘:’ . $password);
        
       $buffer = curl_exec($curl_handle);
       curl_close($curl_handle);
        
       $result = json_decode($buffer);
 
       if(isset($result->status) && $result->status == ‘success’)
       {
           echo ‘User has been updated.’;
       }
        
       else
       {
           echo ‘Something has gone wrong’;
       }
   }

Взаимодействие с вашим API этим способом работает нормально, но с этим методом есть две проблемы:

  1. Он использует уродливый запутанный синтаксис — представьте, что вы создадите несколько приложений на его основе.
  2. cURL не установлен на всех серверах по умолчанию.

Чтобы решить этот уродливый синтаксис, для CodeIgniter была разработана библиотека cURL, которая значительно упрощает работу.

Точно такой же запрос, сделанный с библиотекой cURL, будет выглядеть так:

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
function ci_curl($new_name, $new_email)
   {
       $username = ‘admin’;
       $password = ‘1234’;
        
       $this->load->library(‘curl’);
        
       $this->curl->create(‘http://localhost/restserver/index.php/example_api/user/id/1/format/json’);
        
       // Optional, delete this line if your API is open
       $this->curl->http_login($username, $password);
 
       $this->curl->post(array(
           ‘name’ => $new_name,
           ’email’ => $new_email
       ));
        
       $result = json_decode($this->curl->execute());
 
       if(isset($result->status) && $result->status == ‘success’)
       {
           echo ‘User has been updated.’;
       }
        
       else
       {
           echo ‘Something has gone wrong’;
       }
   }

Намного приятнее смотреть правильно? Что ж, есть еще более простой способ работы с REST в ваших приложениях CodeIgniter.

Была разработана клиентская библиотека REST, которая находится поверх этой библиотеки cURL, которая обрабатывает преобразование формата, логины HTTP и некоторые другие аспекты вашего REST API.

01
02
03
04
05
06
07
08
09
10
11
12
13
function rest_client_example($id)
   {
       $this->load->library(‘rest’, array(
           ‘server’ => ‘http://localhost/restserver/index.php/example_api/’,
           ‘http_user’ => ‘admin’,
           ‘http_pass’ => ‘1234’,
           ‘http_auth’ => ‘basic’ // or ‘digest’
       ));
        
       $user = $this->rest->get(‘user’, array(‘id’ => $id), ‘json’);
        
       echo $user->name;
   }

Здесь вы можете видеть, что мы делаем запрос GET, отправляем id в качестве параметра и сообщаем библиотеке, что мы хотим, чтобы в качестве формата контента был указан «json». Это обрабатывает настройку Content-type для вас и преобразует данные в объект PHP для вас. Вы можете изменить это значение на «xml», «json», «serialize», «php», «csv» или любой другой MIME-тип, который вам нравится, например:

1
$user = $this->rest->get(‘user’, array(‘id’ => $id), ‘application/json’);

Как вы уже догадались, как и $ this-> rest-> get (), библиотека также поддерживает $ this-> rest-> post (), $ this-> rest-> put (), $ this-> rest -> delete (), чтобы соответствовать всем вашим методам REST_Controller.

Вам нужно будет получить результаты var_dump (), поступающие из клиентской библиотеки REST, чтобы убедиться, что вы получаете правильный формат данных. Конверсия иногда будет массивом, а иногда и объектом, в зависимости от того, как он конвертируется PHP. Если возвращенный MIME-тип не поддерживается, он просто возвращает формат в виде простого текста.

Используя эту библиотеку REST, вы можете общаться с другими службами RESTful, такими как Twitter и Facebook. Вот простой пример того, как вы можете получить подробную информацию для конкретного пользователя на основе его идентификатора, используя формат Twitter по умолчанию XML.

1
2
3
$this->load->library(‘rest’, array(‘server’ => ‘http://twitter.com/’));
        
       $user = $this->rest->get(‘users/show’, array(‘screen_name’ => ‘philsturgeon’));
1
2
3
4
5
6
7
8
$this->load->library(‘rest’, array(
           ‘server’ => ‘http://twitter.com/’,
           ‘http_user’ => ‘username’,
           ‘http_pass’ => ‘password’,
           ‘http_auth’ => ‘basic’
       ));
        
       $user = $this->rest->post(‘statuses/update.json’, array(‘status’ => ‘Using the REST client to do stuff’));

Глядя на это, вы заметите, что взаимодействие с API Twitter немного отличается в нескольких отношениях.

  1. Они поддерживают переключение формата на основе URL в форме .json вместо / format / json. Некоторые требуют расширения, некоторые нет; так что лучше всегда их добавлять.
  2. Они в основном поддерживают только GET / POST, но начинают добавлять больше методов DELETE.
  3. У них не всегда есть только ресурс в их URL, например: users / search — это один метод REST, а списки — другой.

Следите за этими различиями, так как они могут вас поймать. Если вы застряли, просто введите $ this-> rest-> debug () для получения всей информации по вашему запросу REST.

Объединяя то, что вы теперь знаете о службах RESTful, клиентской библиотеке REST CodeIgniter и документации API-интерфейса Twitter или любой другой документации по API-интерфейсу RESTful, вы можете создавать очень мощные приложения, которые интегрируются с любыми пользовательскими или общедоступными веб-службами с использованием REST. Вы можете расширить свой API, создав больше REST_Controller’ов и даже создать модульный API, используя Matchbox или Modular Separation, чтобы создать контроллер api.php для каждого модуля, чтобы поддерживать ваш API так же аккуратно, как и ваше приложение.

Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для получения лучших учебных материалов по веб-разработке. И не забудьте проверить полезные скрипты и приложения CodeIgniter на Envato Market.