Correct way of implementing a service layer in CodeIgniter applications Correct way of implementing a service layer in CodeIgniter applications codeigniter codeigniter

Correct way of implementing a service layer in CodeIgniter applications


Please note, this is not necessarily the correct way of doing it, but I'm going to explain how a framework like might typically do it and then you can learn about other methods and decide the best one for your use-case. Therefore, I do not expect this answer to be the correct one, but I hope it imparts at least a little knowledge on how things are done before someone who actually knows what they're talking about comes along and chimes in (also to those people - please feel free to edit / downvote this answer :D). Finally this also has nothing to do with CodeIgniter but frameworks in general. Your question should not only be framed as framework-agnostic, but language-agnostic also.

So I'm going to offer an opinion here and that is of the fact that all modern frameworks, specifically in PHP, do not do MVC. Why is this important? Because we all need to be speaking the same language, and 'mvc' does not exist in PHP. That's a fact. Accept that and then we can move forward onto the bastardization of the concept that frameworks use; and CodeIgnitor is a particularly great example of 'MVC' bastardization; henceforth known as "mvc" with quotes.

The plus side is that frameworks like Symfony, for example, provide an initial opinionated architecture that at least contains some form of consistency across the application, and it goes something like this:

  1. A standard HTTP request comes in and hits the front-controller, typically app.php or app_dev.php depending on whether or not you are in development or production; one involves a lot of caching that needs to be run on each change and the other doesn't - which is perfect for development.

  2. A router matches the current url to a controller class and an 'action' (method) within that class.

  3. The dependency injection part of the framework figures out what objects are needed for everything from the controller forward into the model layer and back, and either instantiates or prepares to instantiate them when needed.

  4. The controller is instantiated with any required dependencies and the relevant method is executed. This is typically where you would start your development and 'hook your code in' to the framework.

  5. This is where you decide on your architecture, however, the most important thing from both a developer perspective and business perspective (for lower costs for future maintenance) is consistency.

  6. I personally prefer to ensure my code is decoupled from the framework. I pass in scalars taken from the request into an application-layer service, which uses objects from the model layer (passed-in via DI) to use domain objects. The point here is that domain objects are not directly passed into the controller, they are proxied through an application-layer medium, so you can theoretically replace the entire framework surrounding this and still, all you need to do is pass those scalars into this layer before they hit the model layer and it'll all still work (think CLI calls, no more controllers).

  7. The application-level service uses any required Repositories, Services etc (and passes those scalars into them, remember the separation?), which perform business logic, (typically these are where your design patterns come into play on a day-to-day basis), and then return that data to the application-level service.

  8. The service then returns the data to the controller and guess what? This is where frameworks tend to fuck up! Because there is no concept of a "View" in today's frameworks. There is only a template, and you pass that data to a template and bam that's it. So in your diagram, there is absolutely no concept of a view because that's not how things are done. And to be entirely honest, I'm still using templates because they're the fastest way of doing things, but until modern frameworks get their shit together and actually start using Views, we're out of luck and have to remain steadfast when confronting the fact that some (like Laravel) refer to themselves as "mvc" frameworks.

Note, Fabien Potencier explicitly states that Symfony was not an MVC framework - at least he knows what he's talking about there. Again, this is not purist, it's important we're all speaking the same, factually correct language in computing.

So, because you like diagrams so much, here's how some might do it with today's frameworks...

architectureThis is for an application that has the concept of a Review and Criteria for each Review. And don't even get me started on Symfony forms, they're so coupled to everything they're not a serious part of any architecture.

How many effing layers do you need? We already have "MVC", in DDD we have the concept of "Application", "Domain" and "Infrastructure" seperation, so get those two working together first, then this "service layer"? Do you really need another layer, or is the above enough? Things to think about...

Extra architecture

See, you're not stuck with the framework / http request to get the application going as a result of this separation.

See the "services" in the above diagram? They're separated from the controller so you can throw scalars from anywhere and the application will still work. I think this will give you the separation you need. It's great to do things the right way, learn how to do it, and then learn how to control yourself and be pragmatic about it when it comes to the business and it's needs, but frameworks need to sort their stuff out - and you certainly wont be writing lovely code with CodeIgniter ;)


Dependency Injection and the Adapter pattern would be a good place to start.CodeIgniter support's neither out of the box, so you would need to write a wrapper or maybe a hook.

Your view could only support xml|html as json would need to be pre-rendered to a .json file and then returned as output but this would need to be done via code, it's easier just to return the object in that case and altered on the frontend. PHP is an embedded language which works with (xml|html)

A service model works best when it is injected(dependency injection)into a controller/model and is listed as a property of that controller/model.

The service is then bound to an interface

For example facebook/twitterThey both have a request and response function but both follow similar patterns, yet have different endpoints.

interface SocialMediaAdapter{  public request(url);  public response();}

public class FaceBookProvider implements SocialMediaAdapter{     public request(url){     }     public response(){     }

}

public class TwitterProvider implements SocialMediaAdapter    {         public request(url){         }         public response(){         }    }

public class SocialMediaServiceProvider{    protected $provider = null;    public function constructor(SocialMediaAdapter $provider){       $this->provider = $provider;    }    public function fetch($url){       return $this->provider->request($url);    }}

Dependency Injection required here

new MyController( new SocialMediaServiceProvider ( new FacebookService ) )


IMHO there is no right or wrong here:

option #1 - If you want to re-use the service layer in multiple controllers / actions and feed it data from different models based on the request it makes sense to go for the first one.

option 2# - However the first option could be problematic if your data model is more complicated. What if a second call to the model is needed based on the data of a first call? Using the controller for this business logic defies the whole purpose of the service layer. In this case it might be better to go for the second one.

I think the second one is the more common one.