Laravel, извлекающий данные из REST API
Итак, у меня следующая ситуация:
Система, которую я создаю, извлекает данные из api REST и сохраняет эти данные в базе данных. Что мне интересно, так это как это может быть реализовано и куда приведет подобное поведение в смысле структуры Laravels (контроллер, модель и т.д.)? Есть ли в Laravel встроенный механизм для извлечения данных из внешних источников?
5 answers
Сначала вы должны проложить маршруты в своем app/routes.php
/*
API Routes
*/
Route::group(array('prefix' => 'api/v1', 'before' => 'auth.basic'), function()
{
Route::resource('pages', 'PagesController', array('only' => array('index', 'store', 'show', 'update', 'destroy')));
Route::resource('users', 'UsersController');
});
Примечание: Если вам не требуется аутентификация для вызова API, вы можете удалить 'before' => 'auth.basic'
Здесь вы можете получить доступ к index, store, show, update and destroy
методам из вашего PagesController
.
И URL-адреса запросов будут следующими:
GET http://localhost/project/api/v1/pages // this will call index function
POST http://localhost/project/api/v1/pages // this will call store function
GET http://localhost/project/api/v1/pages/1 // this will call show method with 1 as arg
PUT http://localhost/project/api/v1/pages/1 // this will call update with 1 as arg
DELETE http://localhost/project/api/v1/pages/1 // this will call destroy with 1 as arg
Запрос CURL командной строки будет выглядеть следующим образом (здесь имя пользователя и пароль admin
) и предполагает, что у вас есть .htaccess
файл для удаления index.php
из URL,
curl --user admin:admin localhost/project/api/v1/pages
curl --user admin:admin -d 'title=sample&slug=abc' localhost/project/api/v1/pages
curl --user admin:admin localhost/project/api/v1/pages/2
curl -i -X PUT --user admin:admin -d 'title=Updated Title' localhost/project/api/v1/pages/2
curl -i -X DELETE --user admin:admin localhost/project/api/v1/pages/1
Далее, вы в вашей папке app/controllers
есть два контроллера с именами PagesController.php
и UsersController.php
.
В PagesController.php,
<?php
class PagesController extends BaseController {
/**
* Display a listing of the resource.
*
* @return Response
* curl --user admin:admin localhost/project/api/v1/pages
*/
public function index() {
$pages = Page::all();;
return Response::json(array(
'status' => 'success',
'pages' => $pages->toArray()),
200
);
}
/**
* Store a newly created resource in storage.
*
* @return Response
* curl --user admin:admin -d 'title=sample&slug=abc' localhost/project/api/v1/pages
*/
public function store() {
// add some validation also
$input = Input::all();
$page = new Page;
if ( $input['title'] ) {
$page->title =$input['title'];
}
if ( $input['slug'] ) {
$page->slug =$input['slug'];
}
$page->save();
return Response::json(array(
'error' => false,
'pages' => $page->toArray()),
200
);
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
* curl --user admin:admin localhost/project/api/v1/pages/2
*/
public function show($id) {
$page = Page::where('id', $id)
->take(1)
->get();
return Response::json(array(
'status' => 'success',
'pages' => $page->toArray()),
200
);
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
* curl -i -X PUT --user admin:admin -d 'title=Updated Title' localhost/project/api/v1/pages/2
*/
public function update($id) {
$input = Input::all();
$page = Page::find($id);
if ( $input['title'] ) {
$page->title =$input['title'];
}
if ( $input['slug'] ) {
$page->slug =$input['slug'];
}
$page->save();
return Response::json(array(
'error' => false,
'message' => 'Page Updated'),
200
);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
* curl -i -X DELETE --user admin:admin localhost/project/api/v1/pages/1
*/
public function destroy($id) {
$page = Page::find($id);
$page->delete();
return Response::json(array(
'error' => false,
'message' => 'Page Deleted'),
200
);
}
}
Тогда у вас есть модель с именем Page
, которая будет использовать таблицу с именем pages
.
<?php
class Page extends Eloquent {
}
Вы можете использовать генераторы Laravel4 для создания этих ресурсов с помощью команды php artisan generator
. Прочитайте здесь.
Таким образом, используя эту группировку маршрутов, вы можете использовать одно и то же приложение для выполнения запроса API и в качестве интерфейса.
Редактировать: Buzz не обновлялся более года, теперь рекомендуется использовать Жрать, см. Ответ Мохаммеда Сафира.
Я использовал пакет Buzz для выполнения запросов API.
Вы можете добавить этот пакет, добавив его в раздел require
в вашем файле composer.json
.
{
require: {
"kriswallsmith/buzz": "dev-master"
}
}
Затем запустите composer update
, чтобы установить его.
Затем в Laravel вы можете обернуть его в класс (возможно, класс, подобный хранилищу), который обрабатывает запрос API и возвращает данные для использования вашим приложением.
<?php namespace My\App\Service;
class SomeApi {
public function __construct($buzz)
{
$this->client = $buzz;
}
public function getAllWidgets()
{
$data = $this->client->get('http://api.example.com/all.json');
// Do things with data, etc etc
}
}
Примечание: Это псевдокод. Вам нужно будет создать класс, который будет соответствовать вашим потребностям, и выполнить любую причудливую инъекцию зависимостей или архитектуру кода, которую вы хотите/в которой нуждаетесь.
Как указал @Netbulae, хранилище может вам помочь. Статья , которую он связал, - отличное место для начала. Единственная разница между статьей и тем, что будет делать ваш код, заключается в том, что вместо использования красноречивой модели для получения данные из вашей базы данных, вы делаете запрос API и преобразуете результат в набор массивов/объектов, которые может использовать ваше приложение (по сути, отличается только хранилище данных, что является одним из преимуществ использования класса репозитория в первую очередь).
Мы можем использовать пакет Guzzle в Laravel, это HTTP-клиент PHP для отправки HTTP-запросов.
Вы можете установить Guzzle через composer
composer require guzzlehttp/guzzle:~6.0
Или вы можете указать Guzzle в качестве зависимости в существующем файле composer.json вашего проекта
{
"require": {
"guzzlehttp/guzzle": "~6.0"
}
}
Пример кода в laravel 5 с использованием Guzzle, как показано ниже,
use GuzzleHttp\Client;
class yourController extends Controller {
public function saveApiData()
{
$client = new Client();
$res = $client->request('POST', 'https://url_to_the_api', [
'form_params' => [
'client_id' => 'test_id',
'secret' => 'test_secret',
]
]);
$result= $res->getBody();
dd($result);
}
Вы можете выбрать, что использовать:
- Жрать
- ЗАВИТОК
-
Содержимое файла:
$json = json_decode(file_get_contents('http://host.com/api/v1/users/1'), true);
Попробуйте заглянуть в руководства по внешнему API. Там вы найдете информацию о том, как получить информацию.
Тогда лучший план - создать интерфейс. Проверьте это: http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories/
Вам решать, как вы используете php для решения этой проблемы.