Angular2 and Yii2: Project Structure and Architecture

Angular2 and Yii2

How do you start off using Angular2 (or AngularJS) and Yii2 in a single project? What is a solid project structure / architecture that can be used to combine the two while still maintaining good separation of concerns? I will try to outline a basic folder structure and workflow I have used successfully in the past.

Project Structure

First of all let me show you the final directory structure that I am aiming for. Although I will explain how we get there in the next section, it is good to keep in mind what we are trying to achieve.

The entire project is divided into two sections contained within a base folder (here named as project). The server folder contains a modified form of the Yii2 Advanced Template project structure while the client folder contains the Angular2 files generated using angular-cli. You will typically initialize your git repository in the base project folder.

These two sections of your application, client and server, will communicate using only a REST API. Yii2 has some amazing functionality to quickly develop a standards compliant REST API so that it can be easily consumed by your Angular2 / AngularJS client. In addition, the same API can also be used by any Android or iOS application you probably have planned down the line.

Setting Up Yii2

While Yii2 allows setting up using either composer or a direct downloaded archive file, I very much recommend that you use the composer method. After installing composer, you can use the following commands to setup the Yii2 side of the application using the advanced template.

Do not run the init command yet because there are a couple more tweaks to be done.

Once the advanced template is setup, we have to perform a re-structuring of the folder structure. There is currently a frontend and a backend. Let’s keep the backend folder as the administrative panel of the application. We will rename the frontend to  api and this folder will hold the REST API files. We will not be needing the frontend folder because the Angular2 will be located in the client folder. As you might already know, the common folder in Yii2 is used to hold the files (models, components, etc.) that are common to both api and backend.

In order to do this, we will also have to make some changes in the environment folder. Use the steps below to make these changes:

  • Rename the frontend folder to api
  • Replace all occurrences of frontend inside api folder to api
  • Change the frontend folders in the environment/dev and environment/prod folders to api
  • Replace all occurrences of frontend to api in the environment/index.php file
  • Run the init command and select development.

That is it! Now your folder structure for Yii2 should probably look similar to what I had shown in the starting of this article. I also like to set virtual hosts to point to my backend and api folders on my server. I would suggest something like admin.project.dev and api.project.dev for these.

Setting Up Angular2

Setting up angular2 is going to be a lot simpler since we are going to make use of the angular-cli tool. First of all you have to make sure that node.js and npm are installed. This should be easy enough on mac and linux. If you are on windows, you can use this tutorial on installing them.

Once node.js and npm are installed, you can install angular-cli globally using the following command:

After this, navigate to your project root folder and run the following command to create a new angular2 project:

This will probably take some time because it runs npm update to pull all the packages that are required for angular2 development. But once it is ready, you can navigate into that folder and run ng serve to start a development server. The default port is 4200.

Also, if you would like to, you can specify a virtual host. I would suggest something like app.project.dev:4200.

Setup RESTful Service to communicate with Angular2

Finally, I would like to explore a little about how to quickly develop our own REST API using Yii2. Using just a couple of lines of code, you can almost completely, setup a basic REST API.

I will try to explain using an example. Suppose you have a model named Car based on a table that has a couple of fields like make, model and capacity. All you have to do in order to expose a REST API for this table is:

  1. Create a controller that extends from yii\rest\ActiveController same as below.
  2. Add a URL Rule to your configuration file.

Now, the Car API is exposed and based on our virtual host setup earlier, we can invoke the API as such: http://api.project.dev/cars. This will return either an XML or JSON (depending on the acceptable content type) data for all the cars in the table. All this while neatly paginating the results as well. The following end points are automatically defined for the cars resource and can therefore be called from your angular2 instance:

  • GET /cars: list all cars page by page;
  • POST /cars: create a new car;
  • GET /cars/123: return the details of the car 123;
  • PATCH /cars/123 and PUT /cars/123: update the car 123;
  • DELETE /cars/123: delete the car 123;

Notice how Yii2 automatically pluralizes the resource end points. You can find out more about Yii2 resources and other RESTful web services features here. Also, feel free to leave your comments and suggestions as well as other project structures you may have used to achieve better results.

Comments

  1. Massimo Simonini says:

    Setting up Yii2, after “Rename the frontend folder to api” you have to replace all occurrences of “frontend” inside “api” folder to “api”.

    1. Admin says:

      Yes, that is correct. I have added that step now. Thank you.

  2. Dalmiro says:

    Where do we implement the views that we are going to work with angular? In the server folder or in the client folder? Thank you

    1. Admin says:

      That would be the client folder.

      1. Dalmiro says:

        Is it possible to work backend views with angular? Or it is better to work these from the backend folder of the same yii ?

        1. Admin says:

          I’m not sure I understand your question entirely. In the structure I have proposed, the entire backend (or the administration portion) and it’s views are expected to be developed using Yii2 itself. Only the frontend portion (or end-user portion) of the site will be developed using pure Angular. Hope that helps…

  3. Prashant says:

    Can you please tell me how to run the example of angular2 in yii2?

  4. Prashant says:

    I have gone through all the steps.
    Now I want to run the application. How to do it? can you please tell me the steps so i will again follow that.
    Regards,
    Prashant

    1. Admin says:

      You can run using the command “ng serve” from the client folder. Then your angular application should be accessible either through localhost:4200 or through app.project.dev:4200 if you have made the necessary changes in hosts file to set up the virtual hosts.

  5. sergio says:

    i have these error:
    An Error occurred while handling another error:
    yii\base\InvalidRouteException: Unable to resolve the request “site/error”. in /Applications/MAMP/htdocs/yii_angular_advanceerp/vendor/yiisoft/yii2/base/Module.php:532
    Stack trace:
    #0 /Applications/MAMP/htdocs/yii_angular_advanceerp/vendor/yiisoft/yii2/web/ErrorHandler.php(95): yii\base\Module->runAction(‘site/error’)
    #1 /Applications/MAMP/htdocs/yii_angular_advanceerp/vendor/yiisoft/yii2/base/ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\NotFoundHttpException))
    #2 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\NotFoundHttpException))
    #3 {main}
    Previous exception:
    yii\web\NotFoundHttpException: Page not found. in /Applications/MAMP/htdocs/yii_angular_advanceerp/vendor/yiisoft/yii2/web/Request.php:193
    Stack trace:
    #0 /Applications/MAMP/htdocs/yii_angular_advanceerp/vendor/yiisoft/yii2/web/Application.php(82): yii\web\Request->resolve()
    #1 /Applications/MAMP/htdocs/yii_angular_advanceerp/vendor/yiisoft/yii2/base/Application.php(380): yii\web\Application->handleRequest(Object(yii\web\Request))
    #2 /Applications/MAMP/htdocs/yii_angular_advanceerp/api/web/index.php(17): yii\base\Application->run()
    #3 {main}

    The structure is yii_anguar_advance > vendor > yiisoft > yii2 > rest > UrlRule.php
    maybe the use yii\rest\ActiveController

    1. Dalmiro says:

      You have to change in the path /common/config/bootstrap.php frontend for api

  6. Ali says:

    localhost:4200/api/cars not sending request to the rest controller

Leave a Reply

Your email address will not be published. Required fields are marked *