Skip to content

Commit

Permalink
Extract api to separate application
Browse files Browse the repository at this point in the history
  • Loading branch information
Eugene Terentev committed Apr 23, 2018
1 parent 23273e6 commit 0146734
Show file tree
Hide file tree
Showing 74 changed files with 560 additions and 13,654 deletions.
4 changes: 4 additions & 0 deletions .env.dist
Expand Up @@ -22,6 +22,7 @@ TEST_DB_PASSWORD = root

# Urls
# ----
API_HOST_INFO = http://api.yii2-starter-kit.localhost
FRONTEND_HOST_INFO = http://yii2-starter-kit.localhost
BACKEND_HOST_INFO = http://backend.yii2-starter-kit.localhost
STORAGE_HOST_INFO = http://storage.yii2-starter-kit.localhost
Expand Down Expand Up @@ -55,3 +56,6 @@ GLIDE_MAX_IMAGE_SIZE = 4000000

# To resolve "Invalid volumes",For Toolbox. (https://github.com/docker/toolbox/issues/607)
COMPOSE_CONVERT_WINDOWS_PATHS=1

# Config for Docker for Mac
#XDEBUG_CONFIG = "remote_connect_back=0 remote_host=host.docker.internal"
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -25,6 +25,7 @@ install:
before_script:
- docker-compose exec -T app php console/yii app/setup --interactive=0
- docker-compose exec -T app php console/yii app/truncate --interactive=0
- docker-compose exec -T app ./vendor/bin/codecept build

script:
- docker-compose exec -T app php -S 127.0.0.1:8080 > /dev/null 2>&1 &
Expand Down
17 changes: 17 additions & 0 deletions api/config/_cache.php
@@ -0,0 +1,17 @@
<?php
/**
* @author Eugene Terentev <eugene@terentev.net>
*/

$cache = [
'class' => yii\caching\FileCache::class,
'cachePath' => '@api/runtime/cache'
];

if (YII_ENV_DEV) {
$cache = [
'class' => yii\caching\DummyCache::class
];
}

return $cache;
10 changes: 10 additions & 0 deletions api/config/_urlManager.php
@@ -0,0 +1,10 @@
<?php
return [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
// Api
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/article', 'only' => ['index', 'view', 'options']],
]
];
9 changes: 9 additions & 0 deletions api/config/base.php
@@ -0,0 +1,9 @@
<?php
return [
'id' => 'frontend',
'basePath' => dirname(__DIR__),
'components' => [
'urlManager' => require(__DIR__ . '/_urlManager.php'),
'cache' => require(__DIR__ . '/_cache.php'),
],
];
4 changes: 4 additions & 0 deletions api/config/bootstrap.php
@@ -0,0 +1,4 @@
<?php
/**
* @author Eugene Terentev <eugene@terentev.net>
*/
4 changes: 4 additions & 0 deletions api/config/console.php
@@ -0,0 +1,4 @@
<?php
return [

];
36 changes: 36 additions & 0 deletions api/config/web.php
@@ -0,0 +1,36 @@
<?php
$config = [
'homeUrl' => Yii::getAlias('@apiUrl'),
'controllerNamespace' => 'api\controllers',
'defaultRoute' => 'site/index',
'bootstrap' => ['maintenance'],
'modules' => [
'v1' => \api\modules\v1\Module::class
],
'components' => [
'errorHandler' => [
'errorAction' => 'site/error'
],
'maintenance' => [
'class' => common\components\maintenance\Maintenance::class,
'enabled' => function ($app) {
if (env('APP_MAINTENANCE') === '1') {
return true;
}
return $app->keyStorage->get('frontend.maintenance') === 'enabled';
}
],
'request' => [
'enableCookieValidation' => false,
],
'user' => [
'class' => yii\web\User::class,
'identityClass' => common\models\User::class,
'loginUrl' => ['/user/sign-in/login'],
'enableAutoLogin' => true,
'as afterLogin' => common\behaviors\LoginTimestampBehavior::class
]
]
];

return $config;
30 changes: 30 additions & 0 deletions api/controllers/SiteController.php
@@ -0,0 +1,30 @@
<?php declare(strict_types=1);

namespace api\controllers;

use Yii;
use yii\web\Controller;
use yii\web\NotFoundHttpException;

class SiteController extends Controller
{
public function actionIndex()
{
return $this->redirect(\Yii::getAlias('@frontendUrl'));
}

public function actionError()
{
if (($exception = Yii::$app->getErrorHandler()->exception) === null) {
$exception = new NotFoundHttpException(Yii::t('yii', 'Page not found.'));
}

if ($exception instanceof \HttpException) {
Yii::$app->response->setStatusCode($exception->getCode());
} else {
Yii::$app->response->setStatusCode(500);
}

return $this->asJson(['error' => $exception->getMessage(), 'code' => $exception->getCode()]);
}
}
47 changes: 47 additions & 0 deletions api/modules/v1/Module.php
@@ -0,0 +1,47 @@
<?php

namespace api\modules\v1;

use Yii;
use yii\filters\ContentNegotiator;
use yii\filters\RateLimiter;
use yii\web\Response;

class Module extends \yii\base\Module
{
/** @var string */
public $controllerNamespace = 'api\modules\v1\controllers';

/**
* @inheritdoc
*/
public function init()
{
parent::init();
Yii::$app->user->identityClass = 'api\modules\v1\models\ApiUserIdentity';
Yii::$app->user->enableSession = false;
Yii::$app->user->loginUrl = null;
}

/**
* @return array
*/
public function behaviors()
{
$behaviors = parent::behaviors();

$behaviors['contentNegotiator'] = [
'class' => ContentNegotiator::class,
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
];

$behaviors['rateLimiter'] = [
'class' => RateLimiter::class,
];

return $behaviors;
}
}
@@ -1,10 +1,14 @@
<?php

namespace frontend\modules\api\v1\controllers;
namespace api\modules\v1\controllers;

use frontend\modules\api\v1\resources\Article;
use api\modules\v1\resources\Article;
use yii\data\ActiveDataProvider;
use yii\rest\ActiveController;
use yii\rest\IndexAction;
use yii\rest\OptionsAction;
use yii\rest\Serializer;
use yii\rest\ViewAction;
use yii\web\HttpException;

/**
Expand All @@ -16,12 +20,12 @@ class ArticleController extends ActiveController
/**
* @var string
*/
public $modelClass = 'frontend\modules\api\v1\resources\Article';
public $modelClass = 'api\modules\v1\resources\Article';
/**
* @var array
*/
public $serializer = [
'class' => 'yii\rest\Serializer',
'class' => Serializer::class,
'collectionEnvelope' => 'items'
];

Expand All @@ -32,17 +36,17 @@ public function actions()
{
return [
'index' => [
'class' => 'yii\rest\IndexAction',
'class' => IndexAction::class,
'modelClass' => $this->modelClass,
'prepareDataProvider' => [$this, 'prepareDataProvider']
],
'view' => [
'class' => 'yii\rest\ViewAction',
'class' => ViewAction::class,
'modelClass' => $this->modelClass,
'findModel' => [$this, 'findModel']
],
'options' => [
'class' => 'yii\rest\OptionsAction'
'class' => OptionsAction::class
]
];
}
Expand Down
60 changes: 60 additions & 0 deletions api/modules/v1/controllers/UserController.php
@@ -0,0 +1,60 @@
<?php

namespace api\modules\v1\controllers;

use common\models\User;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\HttpHeaderAuth;
use yii\filters\auth\QueryParamAuth;
use yii\rest\Controller;
use yii\rest\OptionsAction;

/**
* @author Eugene Terentev <eugene@terentev.net>
*/
class UserController extends Controller
{
/**
* @return array
*/
public function behaviors()
{
$behaviors = parent::behaviors();

$behaviors['authenticator'] = [
'class' => CompositeAuth::class,
'authMethods' => [
HttpBasicAuth::class,
HttpBearerAuth::class,
HttpHeaderAuth::class,
QueryParamAuth::class
]
];

return $behaviors;
}

/**
* @inheritdoc
*/
public function actions()
{
return [
'options' => [
'class' => OptionsAction::class
]
];
}

/**
* @return User|null|\yii\web\IdentityInterface
*/
public function actionIndex()
{
$resource = new User();
$resource->load(\Yii::$app->user->getIdentity()->attributes, '');
return $resource;
}
}
@@ -1,6 +1,6 @@
<?php

namespace frontend\modules\api\v1\models;
namespace api\modules\v1\models;

use common\models\User;
use Yii;
Expand Down
@@ -1,6 +1,6 @@
<?php

namespace frontend\modules\api\v1\resources;
namespace api\modules\v1\resources;

use yii\helpers\Url;
use yii\web\Link;
Expand Down
@@ -1,6 +1,6 @@
<?php

namespace frontend\modules\api\v1\resources;
namespace api\modules\v1\resources;

/**
* @author Eugene Terentev <eugene@terentev.net>
Expand Down
2 changes: 2 additions & 0 deletions api/runtime/.gitignore
@@ -0,0 +1,2 @@
*
!.gitignore
29 changes: 29 additions & 0 deletions api/web/index-test.php
@@ -0,0 +1,29 @@
<?php
require(__DIR__ . '/../../tests/bootstrap.php');

// NOTE: Make sure this file is not accessible when deployed to production
if (YII_ENV !== 'test') {
die('You are not allowed to access this file.');
}

// Environment
require(__DIR__ . '/../../common/env.php');

// Yii
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');

// Bootstrap application
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/base.php'),
require(__DIR__ . '/../../common/config/web.php'),
require(__DIR__ . '/../config/base.php'),
require(__DIR__ . '/../config/web.php'),
require(__DIR__ . '/../../tests/config/base.php'),
require(__DIR__ . '/../../tests/config/common/acceptance.php'),
require(__DIR__ . '/../../tests/config/frontend/acceptance.php')
);

(new yii\web\Application($config))->run();
22 changes: 22 additions & 0 deletions api/web/index.php
@@ -0,0 +1,22 @@
<?php
// Composer
require(__DIR__ . '/../../vendor/autoload.php');

// Environment
require(__DIR__ . '/../../common/env.php');

// Yii
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');

// Bootstrap application
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');

$config = \yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/base.php'),
require(__DIR__ . '/../../common/config/web.php'),
require(__DIR__ . '/../config/base.php'),
require(__DIR__ . '/../config/web.php')
);

(new yii\web\Application($config))->run();

0 comments on commit 0146734

Please sign in to comment.