RESTful API сложны! Есть много аспектов для разработки и написания успешного. Например, некоторые темы, которые вы можете решить самостоятельно, включают аутентификацию, гипермедиа / HATEOS, управление версиями, ограничения скорости и согласование контента. Однако вместо того, чтобы заниматься всеми этими концепциями, давайте вместо этого сосредоточимся на основах REST. Мы создадим некоторые конечные точки JSON за базовой системой аутентификации и изучим несколько приемов Laravel 4 в процессе.
Если вам нужна помощь в разработке Laravel, попробуйте некоторые полезные скрипты и плагины Laravel, доступные на Envato Market.
Приложение
Давайте создадим API для простого приложения Read-It-Later. Пользователи смогут создавать, читать, обновлять и удалять URL-адреса, которые они хотят прочитать позже.
Готовы окунуться и начать?
Установите Laravel 4
Создайте новую версию Laravel 4 . Если вам удобно с CLI, попробуйте это краткое руководство . В противном случае у нас есть видеоруководство по Nettuts +, которое освещает этот процесс.
Мы собираемся сначала создать ключ шифрования для безопасного хеширования пароля. Вы можете сделать это легко, запустив эту команду из корня вашего проекта:
1
|
$ php artisan key:generate
|
Кроме того, вы можете просто отредактировать ключ шифрования app/config/app.php
:
01
02
03
04
05
06
07
08
09
10
11
12
|
/*
|—————————————————————————
|
|—————————————————————————
|
|
|
|
|
*/
‘key’ => md5(‘this is one way to get an encryption key set’),
|
База данных
Как только у вас будет рабочая установка Laravel 4, мы сможем начать с веселья. Мы начнем с создания базы данных приложения.
Для этого потребуются только две таблицы базы данных:
- Пользователи , включая имя пользователя и пароль
- URL , включая URL и описание
Мы будем использовать миграции Laravel для создания и заполнения базы данных.
Настройте свою базу данных
Отредактируйте app/config/database.php
и заполните его настройками базы данных. Примечание: это означает создание базы данных для использования этим приложением. Эта статья предполагает базу данных MySQL.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
‘connections’ => array(
‘mysql’ => array(
‘driver’ => ‘mysql’,
‘host’ => ‘localhost’,
‘database’ => ‘read_it_later’,
‘username’ => ‘your_username’,
‘password’ => ‘your_password’,
‘charset’ => ‘utf8’,
‘collation’ => ‘utf8_unicode_ci’,
‘prefix’ => »,
),
),
|
Создать файлы миграции
1
2
|
$ php artisan migrate:make create_users_table —table=users —create
$ php artisan migrate:make create_urls_table —table=urls —create
|
Эти команды устанавливают основные сценарии миграции, которые мы будем использовать для создания таблиц базы данных. Наша задача сейчас — заполнить их правильными столбцами таблицы.
Отредактируйте app/database/migrations/SOME_DATE_create_users_table.php
и добавьте в метод up()
:
01
02
03
04
05
06
07
08
09
10
|
public function up()
{
Schema::create(‘users’, function(Blueprint $table)
{
$table->increments(‘id’);
$table->string(‘username’)->unique();
$table->string(‘password’);
$table->timestamps();
});
}
|
Выше мы устанавливаем имя пользователя (которое должно быть уникальным), пароль, а также временные метки. Сохраните это, и теперь отредактируйте app/database/migrations/SOME_DATE_create_urls_table.php
и добавьте в метод up()
:
01
02
03
04
05
06
07
08
09
10
11
|
public function up()
{
Schema::create(‘urls’, function(Blueprint $table)
{
$table->increments(‘id’);
$table->integer(‘user_id’);
$table->string(‘url’);
$table->string(‘description’);
$table->timestamps();
});
}
|
Единственное важное замечание в этом фрагменте заключается в том, что мы создаем ссылку между url
и таблицей users
через поле user_id
.
Добавить образец пользователей
Мы можем использовать семена Laravel для создания нескольких примеров пользователей.
Создайте файл в папке app/database/seeds
seed, имя которого совпадает с именем таблицы, которой оно соответствует; в нашем случае UserTableSeeder.php
. Добавлять:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
<?php
class UserTableSeeder extends Seeder {
public function run()
{
DB::table(‘users’)->delete();
User::create(array(
‘username’ => ‘firstuser’,
‘password’ => Hash::make(‘first_password’)
));
User::create(array(
‘username’ => ‘seconduser’,
‘password’ => Hash::make(‘second_password’)
));
}
}
|
Далее, убедитесь, что класс seeder запускается при заполнении базы данных. Отредактируйте app/database/seeds/DatabaseSeeder.php
:
1
2
3
4
5
6
7
|
public function run()
{
Eloquent::unguard();
// Add or Uncomment this line
$this->call(‘UserTableSeeder’);
}
|
Запустить миграцию
Вот как создать эти две таблицы и вставить наши примеры пользователей.
1
2
3
4
5
|
// Create the two tables
$ php artisan migrate
// Create the sample users
$ php artisan db:seed
|
модели
Laravel 4 продолжает использовать превосходную Eloquent ORM. Это сделает процесс обработки вызовов базы данных несложным. Нам потребуется одна модель на стол.
К счастью, Laravel поставляется с настройкой модели User, поэтому давайте создадим модель для нашей таблицы URL.
Создайте и отредактируйте файл app/models/Url.php
.
1
2
3
4
5
6
7
|
<?php
class Url extends Eloquent {
protected $table = ‘urls’;
}
|
Аутентификация
Фильтры Laravel могут обрабатывать аутентификацию для нас. В частности, Laravel теперь поставляется с фильтром базовой аутентификации, который мы можем использовать в качестве модели быстрой аутентификации, которая будет использоваться с нашими запросами API.
Если вы откроете app/filters.php
, вы увидите, как это выглядит:
1
2
3
4
|
Route::filter(‘auth.basic’, function()
{
return Auth::basic();
});
|
Нам просто нужно сделать одну настройку. По умолчанию этот фильтр ищет поле «электронная почта» для идентификации пользователя. Поскольку мы используем имена пользователей вместо электронных писем, нам просто нужно изменить это предпочтение. Измените вызов Auth::basic()
указав в качестве параметра наше имя пользователя:
1
2
3
4
|
Route::filter(‘auth.basic’, function()
{
return Auth::basic(«username»);
});
|
Маршруты
Давайте проверим это. Создайте маршрут с именем testauth
и убедитесь, что наш фильтр auth.basic
работает перед ним.
Отредактируйте app/routes.php
:
1
2
3
4
|
Route::get(‘/authtest’, array(‘before’ => ‘auth.basic’, function()
{
return View::make(‘hello’);
}));
|
Мы можем проверить это с помощью запроса curl. С вашего терминала попробуйте указать вашу сборку Laravel. По моему, это выглядит так (Ваш URL, вероятно, будет другим!):
1
2
3
4
5
6
7
8
|
$ curl -i localhost/l4api/public/index.php/authtest
HTTP/1.1 401 Unauthorized
Date: Tue, 21 May 2013 18:47:59 GMT
WWW-Authenticate: Basic
Vary: Accept-Encoding
Content-Type: text/html;
Invalid credentials
|
Как видите, неавторизованный запрос обнаружен, и возвращается сообщение «Invalid Credentials» с кодом состояния 401. Далее попробуйте включить базовую аутентификацию.
1
2
3
4
5
6
7
|
$ curl —user firstuser:first_password localhost/l4api/public/index.php/authtest
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 18:50:51 GMT
Vary: Accept-Encoding
Content-Type: text/html;
<h1>Hello World!</h1>
|
Это сработало!
На этом базовая работа нашего API завершена. У нас есть:
- Установлен Laravel 4
- Создал нашу базу данных
- Созданы наши модели
- Создана модель аутентификации
Создание функциональных запросов
Вы можете быть знакомы с RESTful-контроллерами Laravel. Они все еще существуют в Laravel 4; однако мы также можем использовать Ресурсные контроллеры Laravel, которые устанавливают некоторые парадигмы, которые мы можем использовать для создания согласованного интерфейса API. Мы будем использовать Ресурсный контроллер.
Вот разбивка того, что будет обрабатывать каждый метод в находчивом контроллере. Обратите внимание, что вы можете удалить маршруты / resource / create и / resource / {id} / edit, так как нам не нужно показывать формы «create» или «edit» в API.
Создайте изобретательный контроллер
1
|
$ php artisan controller:make UrlController
|
Затем настройте маршрут для использования контроллера и потребуйте, чтобы каждый маршрут был аутентифицирован.
Отредактируйте app/routes.php
и добавьте:
1
2
3
4
5
|
// Route group for API versioning
Route::group(array(‘prefix’ => ‘api/v1’, ‘before’ => ‘auth.basic’), function()
{
Route::resource(‘url’, ‘UrlController’);
});
|
Там происходит несколько вещей.
- Это будет отвечать на запросы, сделанные на
http://example.com/api/v1/url
. - Это позволяет нам добавлять дополнительные маршруты, если нам нужно расширить наш API. Например, если вы добавите конечную точку пользователя, например
/api/v1/user
. - Существует также механизм именования для управления версиями нашего API. Это дает нам возможность развертывать новые версии API, не ломая старые версии. Мы можем просто создать группу маршрутов v2 и указать ей новый контроллер!
Примечание. Возможно, вы захотите рассмотреть более продвинутые методы управления версиями API, такие как использование заголовка Accept
или субдомена, которые могут помочь вам указать разные версии API на отдельных основах кода.
Добавьте функциональность
Отредактируйте новый файл app/controllers/UrlController.php
:
1
2
3
4
5
|
// Edit this:
public function index()
{
return ‘Hello, API’;
}
|
Давайте проверим это:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
$ curl -i localhost/l4api/public/index.php/api/v1/url
HTTP/1.1 401 Unauthorized
Date: Tue, 21 May 2013 19:02:59 GMT
WWW-Authenticate: Basic
Vary: Accept-Encoding
Content-Type: text/html;
Invalid credentials.
$ curl —user firstuser:first_password localhost/l4api/public/index.php/api/v1/url
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 19:04:19 GMT
Vary: Accept-Encoding
Content-Type: text/html;
Hello, API
|
Теперь у нас есть изобретательный контроллер с работающей аутентификацией, и мы готовы добавить функциональность.
Создать URL
Отредактируйте app/controllers/UrlController.php
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
$url = new Url;
$url->url = Request::get(‘url’);
$url->description = Request::get(‘description’);
$url->user_id = Auth::user()->id;
// Validation and Filtering is sorely needed!!
// Seriously, I’m a bad person for leaving that out.
$url->save();
return Response::json(array(
‘error’ => false,
‘urls’ => $urls->toArray()),
200
);
}
|
Пришло время проверить это с другим запросом curl. Этот отправит запрос POST, который будет соответствовать методу store()
созданному выше.
1
2
3
4
5
6
|
$ curl -i —user firstuser:first_password -d ‘url=http://google.com&description=A Search Engine’ localhost/l4api/public/index.php/api/v1/url
HTTP/1.1 201 Created
Date: Tue, 21 May 2013 19:10:52 GMT
Content-Type: application/json
{«error»:false,»message»:»URL created»}
|
Здорово! Давайте создадим еще несколько для обоих наших пользователей.
1
2
3
4
5
|
$ curl —user firstuser:first_password -d ‘url=http://fideloper.com&description=A Great Blog’ localhost/l4api/public/index.php/api/v1/url
$ curl —user seconduser:second_password -d ‘url=http://digitalsurgeons.com&description=A Marketing Agency’ localhost/l4api/public/index.php/api/v1/url
$ curl —user seconduser:second_password -d ‘url=http://www.poppstrong.com/&description=I feel for him’ localhost/l4api/public/index.php/api/v1/url
|
Далее, давайте создадим методы для получения URL.
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
|
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
//Formerly: return ‘Hello, API’;
$urls = Url::where(‘user_id’, Auth::user()->id)->get();
return Response::json(array(
‘error’ => false,
‘urls’ => $urls->toArray()),
200
);
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
// Make sure current user owns the requested resource
$url = Url::where(‘user_id’, Auth::user()->id)
->where(‘id’, $id)
->take(1)
->get();
return Response::json(array(
‘error’ => false,
‘urls’ => $url->toArray()),
200
);
}
|
Давайте проверим их:
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
|
$ curl —user firstuser:first_password localhost/l4api/public/index.php/api/v1/url
{
«error»: false,
«urls»: [
{
«created_at»: «2013-02-01 02:39:10»,
«description»: «A Search Engine»,
«id»: «2»,
«updated_at»: «2013-02-01 02:39:10»,
«url»: «http://google.com»,
«user_id»: «1»
},
{
«created_at»: «2013-02-01 02:44:34»,
«description»: «A Great Blog»,
«id»: «3»,
«updated_at»: «2013-02-01 02:44:34»,
«url»: «http://fideloper.com»,
«user_id»: «1»
}
]
}
$ curl —user firstuser:first_password localhost/l4api/public/index.php/api/v1/url/1
{
«error»: false,
«urls»: [
{
«created_at»: «2013-02-01 02:39:10»,
«description»: «A Search Engine»,
«id»: «2»,
«updated_at»: «2013-02-01 02:39:10»,
«url»: «http://google.com»,
«user_id»: «1»
}
]
}
|
Почти сделано. Давайте теперь позволим пользователям удалять URL.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
$url = Url::where(‘user_id’, Auth::user()->id)->find($id);
$url->delete();
return Response::json(array(
‘error’ => false,
‘message’ => ‘url deleted’),
200
);
}
|
Теперь мы можем удалить URL, используя запрос DELETE:
1
2
3
4
5
6
|
$ curl -i -X DELETE —user firstuser:first_password localhost/l4api/public/index.php/api/v1/url/1
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 19:24:19 GMT
Content-Type: application/json
{«error»:false,»message»:»url deleted»}
|
Наконец, давайте позволим пользователям обновлять URL.
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
|
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
$url = Url::where(‘user_id’, Auth::user()->id)->find($id);
if ( Request::get(‘url’) )
{
$url->url = Request::get(‘url’);
}
if ( Request::get(‘description’) )
{
$url->description = Request::get(‘description’);
}
$url->save();
return Response::json(array(
‘error’ => false,
‘message’ => ‘url updated’),
200
);
}
|
Чтобы проверить обновления URL, запустите:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
$ curl -i -X PUT —user seconduser:second_password -d ‘url=http://yahoo.com’ localhost/l4api/public/index.php/api/v1/url/4
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 19:34:21 GMT
Content-Type: application/json
{«error»:false,»message»:»url updated»}
// View our changes
$ curl —user seconduser:second_password localhost/l4api/public/index.php/api/v1/url/4
{
«error»: false,
«urls»: [
{
«created_at»: «2013-02-01 02:44:34»,
«description»: «I feel for him»,
«id»: «3»,
«updated_at»: «2013-02-02 18:44:18»,
«url»: «http://yahoo.com»,
«user_id»: «1»
}
]
}
|
Вот и все
Теперь у нас есть начало полнофункционального API. Я надеюсь, что вы многое узнали о том, как запустить API в Laravel 4.
Напомним, что в этом уроке мы достигли следующего:
- Установить Laravel
- Создайте базу данных, используя миграции и заполнение
- Используйте модели Eloquent ORM
- Аутентификация с помощью базовой аутентификации
- Настройка маршрутов, включая управление версиями API
- Создайте функциональность API с помощью Resourceful Controllers
Следующие шаги
Если вы хотите поднять свой API на ступеньку выше, вы можете рассмотреть любое из следующих действий в качестве следующего шага.
- Проверка (подсказка: у Laravel есть библиотека проверки ).
- Обработка ошибок API-запросов — все еще возможно получение HTML-ответа на запросы API (Подсказка: обработка ошибок Laravel , а также согласование содержимого.)
- Согласование содержимого — прослушивание заголовка Accept. (Подсказка: класс запросов Laravel предоставит вам заголовки запросов).
- Проверьте API Craft Google Group .
- Узнайте о различных типах кэширования и о том, как валидационное кэширование может улучшить ваш API.
- Модульное тестирование вашего кода.
- Ознакомьтесь с великолепными API-ресурсами Apigee .
- Попробуйте некоторые полезные скрипты и плагины Laravel, доступные на Envato Market.