I am embarking on creating a Yii project that basically has a shared data model (let's say CerealStuff) with a front-end web site (call it site), admin site admin, and web service ws. I am new to the whole MVC thing and I wanted to know how I should design this project to stay consistent with Yii/MVC best practices. So far I have identified two basic options:
Create models CerealStuff at root, create three modules site, admin, and ws each with their own controllers;
Create models CerealStuff at root, create two modules admin and public with public containing controllers that handle Site and have #soap declarations to handle ws stuff.
I know that option 2 reduces the total amount of reproduced coding but it does not feel as clean quite honestly. Also I feel like maybe a modern web app should be such that even the "site" (view) uses the web service to access the database.
Tell me what to think!
I'm exposing a simple web service in my app, and I went with a separate (soap) controller.
If you follow the fat model / skinny controller paradigm, it's pretty simple to tack on a web service front end to your models.
Edit: better example of fat models: http://www.therailsway.com/2007/6/1/railsconf-recap-skinny-controllers
Read this article to see an example of MVC structured Yii project with two entrance points for front-end and back-end. Once learned this you can add another entrance point easily for ws.
As you can see all models are shared between modules. Controllers, config files and views are separate. Views can be configured as shared as well. I used this type of structure in many projects and never had any issues with extending or scaling.
Related
When should we use multi-module structure (instead simple structure) in php Phalcon?
I have found some multi-module skeleton, such as:
https://github.com/ovr/phalcon-module-skeleton,
https://github.com/phalcon/mvc/tree/master/multiple.
But I don't know should i use this multi-module structure in a project instead use multi projects.
Something i can think about it is: more complex configuration, complex folder structure, my web url be longer (/[module]/[controller]/[action]) and , importantly, performance will be low (for more loading things than).
However, I think that there are something interesting with it (so many ITer had used it). Is there Someone can give me advantages, disadvantages and criterias for selection.
P/s: the same problem with Zend2 Module!
If you are building a single purpose application as an API that does not use Views, you should rather use single module structure. If it will be a realy simple API of for example storing/logging, micro app will do aswell.
Multi module application structure is useful if you are willing to build more complex solutions. For example an public application with public content, but with admin panel. This one would be handy to write in multi-module to separate administrative controllers/views from those public ones.
My habit is to use multi-module structure, because mostly I have to build applications that are CRM's with their API and an public accessible content part (eg. docs). For such purpose it's just handy to create such modules as:
frontend - for controllers accessible by everyone
backend - for controllers accessible after authentication and authorisation like administrative things
API - for API purposes ;)
common - a part I rather am willing not to implement, but in one project I'm forced to put here some abstract controllers that will be extended in other modules.
This way you can keep separate services configuration for each module, what saves you from cutting off things that you are using at purpose of module A, but not on module B. Like authentication part - important for backend, but useless for frontend part. Or Database configuration - slaves for frontend, master for backend, etc. So this may be also a performance-wise solution for big projects.
Update
Sometimes "multi-project" is an option including "multi-module" project ;) It strongly depends on what you are trying to achieve. Eg. if you take API apart, it may be easier to scale it over multiple instances, but at first it costs you an efford to configure separate project.
If system is supposed to be single-server instance or every istance should be absolutely independed on other instances, single multi-module project will be enough - lets say a standar CMS, blog platform, even simple browser game or homepage of mobile app including API for it. But if you are building a whole universum of apps like an internal API to privide content, CRM to manage it and a couple of web pages to serve it, keeping these as separate projects will be easier to manage later.
Well for example I in my application im splitting every functionnality - for example i have model Link - it's splitted to seperate module to have nice application structure where each funtionality is seperated module. It's like less classes to load in loader. Beacause you only need models and routes from each module to load for whole app, and you load other things like librarys/controllers/helpers/services in module.
CakePHP is fantastic, it really deserves the slogan "Rapid Development Framework". I have been able to quickly bake controllers, models and also templates. Things were good for a while until I hit a brick wall. The application I'm developing is way too massive for the simple directory structure offered by default.
Half way in my development process, I started to see myself leaving lots of business logic inside of Table classes. I've heard sayings that it's not a good idea to pollute the model class with behavioral code.
Since my application is large that it requires several modules almost mini applications by themselves I need to use CakePHP a little differently. I will explain the structure of my application that I would prefer.
Application Structure (Architecture)
Core
This folder will contain all the modules my application is made of. Alternatively it should be called "Modules" instead of "Core".
Modules
Each module folder will have a folder for Controllers, Models, Services and Templates.
Model
This will contain two sub folders as the ones already offered by CakePHP 3. It will contain the folders for Entities and Tables. I have heard the table acts as a repository so I have omitted the idea of having a repository folder.
Service
The service folder will contain services for the module, mainly business logic code that uses Table Entities for data persistence and retrieval. This is to help keep the business logic centered and keep the model classes & controller thin.
Controllers
Controllers will be the ones talking with the service classes. Using the services to both retrieve data, save data, do validation, work with business logic...etc. My goal is also to also make the work of the controller very light, by moving most of the logic stuff into services.
Template
This will contain the view files that the controllers will use to render data back to the web browser. I might have sub folders in there for views for sub sections of the module.
Notes & Questions
Please forgive me If I have not explained my self properly, we are dealing with a very complex application that has many tables, approximately 100. If anyone has better recommendations for organizing a large application in CakePHP 3 I would really appreciate it.
By developing my application in this way I understand CakePHP will not work out of the box, I might need to reconfigure it so It can uses my custom directory structure. How easy will it be to do that?
I've started working with Yii for a month (great Framework) and I am now going to build an application, ERP style.
The goal is to have a main application and then, according to user's roles and permissions, have the possibility to navigate (through single sign-on) to the other applications in the ERP.
I read about modules on Yii's docs and although I got the idea, I was left with some doubts.
Surely it is an advantage to have a One Big application with all the branch applications the company needs as modules but what are the limitations?
Or is it preferable to create seperate entire applications instead of modules inside the main App and then navigate through sub-domains?
Its better and preferred to have modules rather than developing separate applications. With modules you can have totally different look and feel just like a separate application. You must have used Gii tool, well that is also a module within your application.
The main advantage with modules is that you wont have to deploy it separately, it is a self contained application in your website. But again that could be a disadvantage if you need to have total separation of these applications.
To learn more about modules see http://www.yiiframework.com/doc/guide/1.1/en/basics.module
I have an application which is developed in Symfony2. Now the structure for it is as follows:
FrontBundle - includes everything related to the application's view and UI.
PersistanceBundle - includes everything related to the persistence layer of the application.
DomainBundle - includes everything related to the entities of the application and the services.
Is this structure ok? Or bundles are used like forum feature - ForumBundle - which includes every layer (controllers, services, domain logic and persistence) related to the forum.
There are no hard and fast rules on how to structure your app using bundles, but here's what I came to after developing on Symfony2 for close to a year.
Use one app specific bundle. At first, I started with multiple bundles like CommonBundle, UserBundle, MainBundle, BlogBundle, ContactBundle, etc. That proved to be not so convenient in the end, so I switched to just one app specific bundle — AppBundle.
You can organize your code neatly using subnamespaces. For example, the backend controllers would go to the AppBundle\Controller\Backend subnamespace.
Note that I'm talking about one app specific bundle — that stuff that's unique to the concrete app and won't make sense to reuse elsewhere. You can still develop separate bundles for reusable stuff and put them into the vendors infrastructure.
Keep non Symfony specific stuff out of bundles. There is no need to have a bundle for the model and the Service Layer classes in a bundle if they are not Symfony2 specific. See this question and my answer for further details.
Like Elnur said, use one AppBundle is a good practice.
A single bundle implements the MVC pattern himself so i think it's not a good idea to use bundles to separate your layers.
I think the best way to use bundles is to think "open source". If the feature you are developping is enough generic to be released for everyone, or to be reused in a future project, place this feature in a bundle.
This way will force you to build the feature without any business rule which belong in your AppBundle.
Bundles are bricks
There are different ways to organise application structure for your projects. But if you want to distribute your bundles and follow symfony best practices, then bundles are more features than separation of UI. More about bundles read in documentation.
I have two projects with the following structures, both valid I think:
making a bundle for each feature: BlogBundle, StoreBundle and so on,
and AppBundle that contains general stuff. No Backend/Frontend
separation. It's SaaS where backend is frontend in most cases.
One bundle for frontend, one for backend. They share only entities
and domain specific stuff. The application has two different ends.
I'm working on a project where the following are in development:
public info website with protected resource areas
web application
Both will be on the same server, under the same domain.
The web application is login protected. If a member logs into the web application, they can also access the protected resource areas on the public site and visa versa.
Q. Both are being developed using CodeIgniter. Because there is need for this shared login, is it advisable to keep both as one project/one big site structure? or 2 separate CI projects/structures with a means of sharing the login.
One developer is tackling the web app and one (me) is tackling the public site - so my feeling is that it would be easier to keep them separate structures with some cross-over for the login/session management.
You might want to consider using a modular system and sharing resources. Codeigniter doesn't have built in modular support, but there are a few packages that will enable it. I've been using the Modular Extensions package for years, and can't imagine using CI without it.
https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home
You may be familiar with the concept already: Each module is basically it's own mini application. It follows the same structure you would see in the Codeigniter application folder. You can even have multiple module directories to separate your application structure even further.
Any shared resources (libraries, helpers, etc) can stay in the default application directory, but if needed you can still cross-load them from other modules. Even if you were working alone, I still would recommend it because it really keeps things organized.
Using modules, you can both work on the application independently, without stepping on each other's toes or even seeing any files that you aren't working with, while having access to the same shared resources (like your Login/Auth model), keeping things extremely organized, and without the hassle of creating two separate applications.
I see no reason why you can't have one shared CI application and just separate the private and public portions within the app. This could be easily accomplished through folder structure within the Controller, Model and View areas. And then, when managing users, you can have a permissions field or table setup to give rights and privileges to the user.
So, for example, you would imagine your sub folders under either Controller, Model or View being: Public, Private and Admin.
Then your users table would have field called "permission" and you can have various levels (i.e. 1, 2, or 3).
Then, in your controller for admin (or whatever) you could have:
function index()
{
if (!this->auth->is_logged_in()) {
redirect('/auth/login');
}
else {
if (!this->auth->is_level(1)){
redirect('/user/notallowed);
}
}
You get the idea.