Yii 2.0 Restful API not working

Hi guys, i’ve been trying to get the restful api working without success. I have followed these tutorials: yiiframework-guide-rest-quick-start, budiirawan.com/setup-restful-api-yii2/, and www.diggin-data.de/dd-cms/blog/post/view/id/1004/name/Creating+a+REST+API+for+Yii2-basic-template, but keep getting Status 500 Internal Server Error. (I’m running Xampp/Win7 with mod_rewrite active).

Directory structure:

app

-api -> index.php, .htaccess

–config -> main.php

–modules -> Module.php

—v1

----controllers -> CountryController.php

----models -> Country.php

-assets

-controllers

-models

CountryController.php

namespace app\api\modules\v1\controllers;

use yii\rest\ActiveController;

class CountryController extends ActiveController {

public $modelClass = 'app\api\modules\v1\models\Country';


//public $modelClass = 'app\models\Country';

}

//both configs of $modelClass gave the same Status 500 error

api/config/main.php

$db = require(DIR . ‘/../../config/db.php’);

$params = require(DIR . ‘/params.php’);

return [

'id' => 'countryapp-api',


'basePath' => dirname(__DIR__),


'bootstrap' => ['log'],


'modules' => [


    'v1' => [


        'basePath' => '@app/api/modules/v1',


        'class' => 'app\api\modules\v1\Module'   // here is our v1 modules


    ]


],


'components' => [


    'request' => [


        'parsers' => [


            'application/json' => 'yii\web\JsonParser',


        ]


    ],


    'user' => [


        'identityClass' => 'app\models\User',


        'enableAutoLogin' => false,


    ],        


    'log' => [


        'traceLevel' => YII_DEBUG ? 3 : 0,


        'targets' => [


            [


                'class' => 'yii\log\FileTarget',


                'levels' => ['error', 'warning'],


            ],


        ],


    ],


    'urlManager' => [


        'enablePrettyUrl' => true,


        'enableStrictParsing' => true,


        'showScriptName' => false,


        'rules' => [


            [


                'class' => 'yii\rest\UrlRule',


                'controller' => 'v1/country',   


                'tokens' => [


                    '{id}' => '<id:\\w+>'


                ]


            ]


        ],


    ]


],


'params' => $params,

];

Please point me in the right direction. Thanks

1 Like

Solved the issues, and thought i would share my experiences

  1. testing api like "localhost/countryapp/v1/countries" DID NOT WORK. Had to configure apache virtualhost for something like "countryapp.dev" which WORKED OK.

  2. changed directory structure following doc-2.0/guide-rest-versioning

  3. removed the api/config/main.php. Did all configs in the config/web.php file

  4. removed ‘enableStrictParsing’ => true under ‘urlManager’, kept breaking the code

  5. in the CountryController.php, I used [public $modelClass = ‘app\models\Country’], there was no need to duplicate the Country model under api/modules

View Code changes

namespace app\modules\api\v1\controllers;

use yii\rest\ActiveController;

class CountryController extends ActiveController {

public $modelClass = 'app\models\Country';

}

modules’ => [

‘v1’ => [ ‘class’ => ‘app\modules\api\v1\Module’ ]

]

I think it would be better to separate your rest config from web app config.

This was my solution:

Directory structure:




mds

|-- api

|   |-- assets

|   |-- common

|   |   `-- models

|   |-- config

|   |-- runtime

|   |   |-- debug

|   |   `-- logs

|   `-- v1

|   	|-- controllers

|   	`-- models

|-- assets

|-- commands

|-- config

|-- controllers

|-- js

|-- mail

|-- messages

|-- models

|-- runtime

|-- tests

|-- vendor

|-- views

|-- www



web app apache config:




/etc/apache2/sites-available/mds.mysite.com

<VirtualHost *:80>

	ServerAdmin webmaster@localhost

	ServerName www.mds.mysite.com

	ServerAlias mds.mysite.com


	DocumentRoot "/var/www/mds/www"


	<Directory /var/www/mds/www/>

		RewriteEngine on

		RewriteCond %{REQUEST_FILENAME} !-f

		RewriteCond %{REQUEST_FILENAME} !-d

		RewriteRule . index.php

		Order allow,deny

		allow from all

	</Directory>


	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

	<Directory "/usr/lib/cgi-bin">

		AllowOverride None

		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

		Order allow,deny

		Allow from all

	</Directory>


	ErrorLog ${APACHE_LOG_DIR}/error.log


	# Possible values include: debug, info, notice, warn, error, crit,

	# alert, emerg.

	LogLevel warn


	CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>



api apache config:




/etc/apache2/sites-available/mdsapi.mysite.com

<VirtualHost *:80>

	ServerAdmin webmaster@localhost

	ServerName mdsapi.mysite.com

	ServerAlias www.mdsapi.mysite.com


	DocumentRoot "/var/www/mds/api"


	<Directory /var/www/mds/api/>

		RewriteEngine on

		RewriteCond %{REQUEST_FILENAME} !-f

		RewriteCond %{REQUEST_FILENAME} !-d

		RewriteRule . index.php

		Order allow,deny

		allow from all

	</Directory>


	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

	<Directory "/usr/lib/cgi-bin">

		AllowOverride None

		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

		Order allow,deny

		Allow from all

	</Directory>


	ErrorLog ${APACHE_LOG_DIR}/error.log


	# Possible values include: debug, info, notice, warn, error, crit,

	# alert, emerg.

	LogLevel warn


	CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>



mds/api/index.php




<?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');


$config = require(__DIR__ . '/config/api.php');


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



mds/api/config/api.php:




<?php


$params = require(__DIR__ . '/../../config/params.php');

$db = require(__DIR__ . '/../../config/db.php');


$config = [

	'id' => 'MdsApi',

	'name' => 'MdsApi',

	'basePath' => dirname(__DIR__) . '/..',

	'bootstrap' => ['log'],

	'modules' => [

    	'v1' => [

        	'basePath' => '@app/api/v1',

        	'class' => 'app\api\v1\Module',

    	],

	],

	'components' => [

    	'db' => $db,

    	'user' => [

        	'identityClass' => 'app\api\common\models\User',

        	'loginUrl' => null,

    	],

    	'request' => [

        	'enableCookieValidation' => false,

        	'parsers' => [

            	'application/json' => 'yii\web\JsonParser',

        	]

    	],

    	'log' => [

        	'traceLevel' => YII_DEBUG ? 3 : 0,

        	'targets' => [

            	[

                	'class' => 'yii\log\FileTarget',

                	'levels' => ['error', 'warning'],

                	'logFile' => '@app/api/runtime/logs/api.log',

            	],

        	],

    	],

    	'urlManager' => [

        	'enablePrettyUrl' => true,

        	'enableStrictParsing' => true,

        	'showScriptName' => false,

        	'rules' => [

            	[

                	'class' => '\yii\rest\UrlRule',

                	'controller' => [

                    	'v1/country',

                	],

            	],

        	],    	

    	],

	],

	'params' => $params,

];


if (YII_ENV_DEV) {

	// configuration adjustments for 'dev' environment

	$config['bootstrap'][] = 'debug';

	$config['modules']['debug'] = [

    	'class' => '\yii\debug\Module',

    	'allowedIPs' => ['127.0.0.1', '::1', '192.168.2.*'],

	];	


	$config['bootstrap'][] = 'gii';

	$config['modules']['gii'] = [

    	'class' => '\yii\gii\Module',

    	'allowedIPs' => ['127.0.0.1', '::1', '192.168.2.*'],

	];

}


return $config;



mds/api/v1/Module.php




<?php

namespace app\api\v1;


class Module extends \yii\base\Module

{


	public $controllerNamespace = 'app\api\v1\controllers';


	public function init()

	{

    	parent::init();

    	\Yii::$app->user->enableSession = false;  

	}

}



mds/api/v1/models/Country.php




<?php

namespace app\api\v1\models;

use \yii\db\ActiveRecord;


class Country extends ActiveRecord 

{

	/**

 	* @inheritdoc

 	*/

	public static function tableName()

	{

		return 'country';

	}


	/**

 	* @inheritdoc

 	*/

	public static function primaryKey()

	{

    	return ['code'];

	}


	/**

 	* Define rules for validation

 	*/

	public function rules()

	{

    	return [

        	[['code', 'name', 'population'], 'required']

    	];

	}   

}



mds/api/v1/controller/CountryController.php




<?php

namespace app\api\v1\controllers;

 

use yii\rest\ActiveController;


class CountryController extends ActiveController

{

	public $modelClass = 'app\api\v1\models\Country';

}



Now in Postman you can list your countries through the path:

http://mdsapi.mysite.com/v1/mobiles

Your web app is on:

http://mds.mysite.com

I tried the same above except apache configurations

my folder structure is

myapp

|-- api

| |-- config

| |-- modules

| | `-- v1

| |-- controllers

| `-- models

         Modules.php 

| |-- runtime

| |-- web

|-- assets

| | `-- css

| `–

|-- assets

|-- commands

|-- config

|-- controllers

|-- mail

|-- models

|-- runtime

|-- tests

|-- vendor

|-- views

|-- web

I try query using http://localhost/myapp/api/web/v1/country

Not found 404 thrown :(

[color="#006400"]/* Moved from "General Discussions" to "REST APIs" */[/color]