If you want to create a REST API for your Yii2 existing web app which uses the basic template and don't want to mess up your web app routes, continue reading.
Directory Structure
This is the basic template's directory structure, after having installed the template (see Yii2 Basic Template):
yourapp + assets + config + controllers + models + views + web ...
Add a new directory structure api in the root folder:
yourapp + web + config + controllers ... + api + config + modules + v1 + controllers .htaccess index.php
Entry Script
- See Yii2 Guide
api/index.php
// comment out the following two lines when deployed to production defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); require(__DIR__ . '/../vendor/autoload.php'); require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'); // Use a distinct configuration for the API $config = require(__DIR__ . '/config/api.php'); (new yii\web\Application($config))->run();
Webserver Configuration
In order to enable pretty URLs, create a .htaccess file.
api/.htaccess
Options +FollowSymLinks IndexIgnore */* RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php
API Configuration
We want to keep configuration settings for the API apart from the web app configuration.
- Create the file api/config/api.php:
$db = require(__DIR__ . '/../../config/db.php'); $params = require(__DIR__ . '/params.php'); $config = [ 'id' => 'basic', 'name' => 'TimeTracker', // Need to get one level up: 'basePath' => dirname(__DIR__).'/..', 'bootstrap' => ['log'], 'components' => [ 'request' => [ // Enable JSON Input: 'parsers' => [ 'application/json' => 'yii\web\JsonParser', ] ], 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], // Create API log in the standard log dir // But in file 'api.log': 'logFile' => '@app/runtime/logs/api.log', ], ], ], 'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ ['class' => 'yii\rest\UrlRule', 'controller' => ['v1/project','v1/time']], ], ], 'db' => $db, 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => false, ], ], 'modules' => [ 'v1' => [ 'class' => 'app\api\modules\v1\Module', ], ], 'params' => $params, ]; return $config;
Module
api/modules/v1/Module.php
// Check this namespace: namespace app\api\modules\v1; class Module extends \yii\base\Module { public function init() { parent::init(); // ... other initialization code ... } }
Controllers
api/modules/v1/controllers/ProjectController.php
namespace app\api\modules\v1\controllers; use yii\rest\ActiveController; class ProjectController extends ActiveController { // We are using the regular web app modules: public $modelClass = 'app\models\Project'; }
Comments
http://budiirawan.com/setup-restful-api-yii2/
and adjusted it according to this one:
https://www.diggin-data.de/dd-cms/blog/post/view/id/1004/name/Creating+a+REST+API+for+Yii2-basic-template
However, when I send a simple GET request using POSTMAN (like: http://localhost/yii2-advanced-api-master/api/web/v1/countries/),
the answer is always the content of index.php and the response status is 200.
That means, the controller is not even reached.
I would appreciate any support.
https://www.cloudways.com/blog/rest-api-yii2/
please for me a explain! thanks so much!
I am using the same approach. But I am facing this issue.
Here is the link.
http://www.yiiframework.com/forum/index.php/topic/71575-yii2-rest-api-call-multiple-methods
Any help would be appriciated.
i am using basic template.
This is my files
api.php
<?php
$db = require(__DIR__ . '/../../config/db.php');
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'name' => 'TimeTracker',
// Need to get one level up:
'basePath' => dirname(__DIR__).'/..',
'bootstrap' => ['log'],
'components' => [
'request' => [
// Enable JSON Input:
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
// Create API log in the standard log dir
// But in file 'api.log':
'logFile' => '@app/runtime/logs/api.log',
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user','v1/time']],
],
],
'urlManager' => [
'class' => 'yii\web\UrlManager',
// Disable index.php
'showScriptName' => false,
// Disable r= routes
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user']],
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
],
],
'db' => $db,
],
'modules' => [
'v1' => [
'class' => 'app\api\modules\v1\Module',
],
],
'params' => $params,
];
return $config;
make sure you copy and past params.php to api/config folder
Then add this libraries to your controller
(I am using usercontroller)
namespace app\api\modules\v1\controllers;
use Yii;
use yii\rest\ActiveController;
use app\models\User;
use yii\data\ActiveDataProvider;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\db\Query;
use yii\helpers\ArrayHelper;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index'=>['get'],
'view'=>['get'],
'create'=>['post'],
'update'=>['post'],
'delete' => ['delete'],
'deleteall'=>['post'],
],
]
];
}
//Other functions after that
}
Your model add this libraries
namespace app\models;
use yii\base\Model;
use yii\db\ActiveRecord;
class User extends ActiveRecord implements \yii\web\IdentityInterface
{
}
Then please add this line to every function in your controller
"\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;"
This will help you to make proper json response.
Example (This is my view function in usercontroller)
public function actionView($id)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$model=$this->findModel($id);
//print_r($model);die;
$this->setHeader(200);
echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
//echo json_encode(array('status'=>1,'data'=>$_GET['id']),JSON_PRETTY_PRINT);
}
I hope you can get solution for using these things
1. User Controller
and api.php file like this
<?php
$db = require(__DIR__ . '/../../config/db.php');
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'name' => 'TimeTracker',
// Need to get one level up:
'basePath' => dirname(__DIR__).'/..',
'bootstrap' => ['log'],
'components' => [
'request' => [
// Enable JSON Input:
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
// Create API log in the standard log dir
// But in file 'api.log':
'logFile' => '@app/runtime/logs/api.log',
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user','v1/time']],
],
],
'db' => $db,
],
'modules' => [
'v1' => [
'basePath' => '@app/api/modules/v1',
'class' => 'app\api\modules\v1\Module' // here is our v1 modules
],
],
'params' => $params,
];
return $config;
Please give me instructions to fix this issue.
if access
rest.local/api/vi/user/
i get blank page and postman app get (No response received, in json)
Thanks
1. User Controller
and api.php file like this
<?php
$db = require(__DIR__ . '/../../config/db.php');
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'name' => 'TimeTracker',
// Need to get one level up:
'basePath' => dirname(__DIR__).'/..',
'bootstrap' => ['log'],
'components' => [
'request' => [
// Enable JSON Input:
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
// Create API log in the standard log dir
// But in file 'api.log':
'logFile' => '@app/runtime/logs/api.log',
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user','v1/time']],
],
],
'db' => $db,
],
'modules' => [
'v1' => [
'basePath' => '@app/api/modules/v1',
'class' => 'app\api\modules\v1\Module' // here is our v1 modules
],
],
'params' => $params,
];
return $config;
Please give me instructions to fix this issue.
if access
rest.local/api/vi/user/
i get blank page and postman app get (No response received, in json)
Thanks
now you can keep using /web to get to your models & take profit of the great debugger tool before moving your code to the api's controllers
Thanks @Narayana for those fixes, it would not work without them.
I also changed one more thing, i placed the config file api.php inside app/config, it make more since to me having all app configurations in one folder, why separate them while we are using global models any way.
A few things. In the api.php, I had to add this line
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => false,
],
had to change module section to following:
'modules' => [
'v1' => [
'basePath' => '@app/api/modules/v1',
'class' => 'app\api\modules\v1\Module' // here is our v1 modules
],
],
Had to add a params.php file. I also built a separate Model file within api/modules/v1/models folder and referred to it in the $modelClass. I am not sure if I could have used the model file in the app/models/ folder.