Небольшой гайд по созданию простейшего RESTful api с помощью Zend framework 2 (далее zf2).
Нам потребуется zf2 v2.3@dev, а так же Doctrine 2 ORM.
Итак, начнем с создания структуры директорий нашего api:
mkdir -pv zf2-api/{config/autoload,public,module/v1/{config,src/v1/{Controller,Service,Entities}}}
Загружаем композер
curl -sS https://getcomposer.org/installer | php
Так же нам потребуется создать composer.json с такими зависимостями и установить их.
"require": {
"php": ">=5.4",
"zendframework/zendframework": "2.*@dev",
"doctrine/doctrine-orm-module" :"0.*"
}
Входную точку public/index.php мы полностью скопируем с zf2 skeleton appliaction:
<?php
chdir(dirname(__DIR__));
// Так же мы возьмем инициализацию автозагрузчика
require 'init_autoloader.php';
define('BASE_DIR', dirname(__DIR__));
// Run the application!
ZendMvcApplication::init(require 'config/application.config.php')->run();
Создаем конфиг application.config.php для запуска нашего приложения, наш модуль будет называется v1 соответственно версии api:
return array(
// Загружаеммые модули
'modules' => array(
'v1',
'DoctrineModule',
'DoctrineORMModule',
),
// Настройка "слушателей для ModuleManager
'module_listener_options' => array(
'module_paths' => array(
'./module',
'./vendor',
),
// Настройка путей для глобальных и локальных конфигов
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
// Включаем проверку зависимости модулей
'check_dependencies' => true,
),
);
Теперь давайте создадим главный класс нашего модуля module/v1/Module.php:
<?php
/**
* Description of Module
*
* @author cawa
*/
namespace v1;
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'ZendLoaderStandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
А так же простейший конфиг для него module/v1/config/module.config.php:
<?php
/**
* Конфиг модуля v1
*
* @author cawa
*/
namespace v1;
return array(
'router' => array(
'routes' => array(
'api' => array(
'type' => 'Segment',
'options' => array(
'route' => '/api/v1/[:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*/?',
),
'defaults' => array(
'__NAMESPACE__' => 'v1Controller',
'controller' => 'v1ControllerIndex',
'action' => 'index'
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'v1ControllerIndex' => 'v1ControllerIndexController',
),
),
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5'
),
'doctrine' => array(
'driver' => array(
__NAMESPACE__ . '_driver' => array(
'class' => 'DoctrineORMMappingDriverAnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
),
'orm_default' => array(
'drivers' => array(
__NAMESPACE__ . 'Entity' => __NAMESPACE__ . '_driver'
)
)
),
),
// Placeholder for console routes
'console' => array(
'router' => array(
'routes' => array(
),
),
),
);
И наш единственный контроллер module/v1/src/v1/Controller/IndexController:
<?php
/*
Document : IndexController
Created on : 28.10.2013, 11:37:11
Author : cawa
Description:
Index controller
*/
namespace v1Controller;
use ZendMvcControllerAbstractRestfulController,
ZendViewModelJsonModel;
class IndexController extends AbstractRestfulController
{
public function indexAction()
{
$em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
$testEntity = $em->getRepository('v1EntityTest')->findAll();
//да не очень хорошее решение, но просто показать подойдет
foreach ($testEntity as $entity) {
$array[] = $entity->getJsonData();
}
return new JsonModel(array('response' => $array));
}
}
Далее запускаем cli сервер php -S localhost:8000 из папки public, и переходим по ссылке localhost:8000/api/v1/index, получаем ответ от сервера.
P.S.
github: zf2-api
Если возникли какие-то вопросы, пишите комментарии, с радостью отвечу.
Если кого-то заинтересует, могу продолжить более подробным гайдом.
Автор: cawakharkov