What are the main differences, in term of performance between service, controller as a service or using a sort of auxiliary object to do the job?
more precisely for this scenario/use-case:
i've got an API on mysite/api, my question is:
Is it better to define a controller as service, a service itself or using in "classical way" as a controller doing all the job with at least an auxiliary object (as a mini-lib) to do most of the job?
auxiliary object I mean use an istance of a class, i suppose everytime the api is called, create the new object (not so good for performance I think).
thanks in advice for your answers.
There won't be any significant performance differences, and all three approaches are absolutely valid, it just matters on your use case.
Thing to note: Controllers are basically services, they are just container aware by default in Symfony (making them Service Locators). It doesn't matter whether controller is a Service, a ContainerAwareInterface object or some object you made, it has to be instantiated either way.
That said, controller is just one of probably hundreds (if not thousands) of objects that will be created on each request and time needed to instantiate it is really negligible.
Use whatever method suits you best.
Edit
Hell, symfony controllers aren't even ContainerAware by default, they are just made so in their examples since they always extendsSymfony\Bundle\FrameworkBundle\Controller\Controller. You can try to make a Controller class like so:
<?php
namespace MyVendor\MyBundle\Controller;
class MyCustomController
{
public function myAction()
{
// do your thing here
}
}
And it will work just fine.
Here is the Symfony code that instantiates controller: ControllerResolver::createController
Basically, it checks whether string matches 'Bundle' pattern or 'Service' pattern. If neither, it just treats it as 'ClassName::methodName', and one way or another: instantiates it.
There is no difference which approach to use. But there are a lot of another questions - rest api routing, formats, documentation etc.
Use ready solution for rest-api gimler/symfony-rest-edition
Related
Well i'm learning Symfony (3.3) and i'm little confused about Service Container. In first tutorial the lector show register, login, add post, edit, delete methods in User, Article Controllers. Then in other tutorial, they show same methods but use Service Container (User and Article services) with User and Article interfaces. So .. what is the best practice for implementation in Services instead of Controllers.
I would like to add to Alexandre's answer that it is considered best practice to keep your controller 'thin'. In other words, only put code in your controller that really has to be there (or if it only makes sense to put it in your controller).
Services are like tools you can use in your application. A service in an object that helps you do something. In one service, you can have many functions. I think the best way to understand the difference is that a controller is for one specific action, a service can be used in many actions. So if you have parts of code that you want to use in more than one controller, create a service for it. And for the sake of re-usability, create functions in your service that do only one thing. This makes it easier along the way to use these functions.
the "best practise" depends on what you want to do with the Service. If you build an REST-Api you might want to do Database-Operations in Controller. Why? When you rely on the SOLID-Pattern you want to reduce or eliminate redundant code. If you code a real REST Api you don't have redundant code because each REST-Verb will do a different query/thing.
So in a non-REST-Api-application you will have a lot of redundant code. You do the same things/services on different pages/controller-actions. So the best thing is to implement all the business-logic in services to have it only one time in one place. If you have a lot of individual queries place them into repositories. If you have business-logic that fit's into an entity-class place them there. So in my opinion you can choose a thick controller/no service design in API's and a thin controller/thick service design in classic symfony front-/backend applications.
But one more thing: there is no totally wrong way to design an application. But if you work with other people or want to run the application longer than a month (without having trouble to maintain it) you should pick a common design-pattern.
Controller must implement the application logic like check if it's a post request or if a form is submit etc...
Never use DQL or any SQL Request directly inside a controller !
EDIT In the example i use a find method inside the controller because it's a Repository method but i parse the result inside slugify (my service method)
Services contains business logic like formatting phone numbers, parse some data etc...
Of course you can inject a repository inside a service and call your methods inside it.
An example:
//This is a fictive example
public function indexAction(Request $request) {
//Application logic
if(!$request->get('id')) {
//redirect somewhere by example
}
$article = $this->getDoctrine()
->getRepository(Article::class)
->find($request->get('id'));
//Business Logic
$slug = $this->get('my.acme.service')->slugify($article->getTitle());
}
Hope this helps
Below are two ways a service layer can be implemented in an CodeIgniter application.
1st method
1.send request to the controller
2.calling service layer methods from controller
3.return processed result data set(D1) from service layer to controller
4.then according to that data set controller demand data from model
5.model return data set(D2) to the controller
6.then controller send second data set(D2) to view.
2nd method
1.send request to the controller
2.calling service layer methods from controller
3.service layer demand data from model
4.model send requested data set(d1) to the service layer
5.after some processing return generated data(d2) to controller from service layer
6.then controller send data set(d2) to view.
What is the correct way of implementing a service layer in CodeIgniter? Other than these two methods, are there any other good ways?
if you can provide an example in Code it will be great
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:
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.
A router matches the current url to a controller class and an 'action' (method) within that class.
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.
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.
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.
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).
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.
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...
This 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...
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/twitter
They 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.
You should use first one. Because in MVC web application, controller is used to separate your business logic from view, it's something like a gateway. You need to start processing your info using controller, from controller you should call model or service layer or anything you need & finally you should return back data to any other source from here. Your view or service layer should not directly access model.
not sure if I'm just too tired and missing something so apologies in advance.
I have a php domain which I need to restructure because ended having an anemic model using services. This is because I'm not using Doctrine but Eloquent by Laravel as my mapper (reasons are due to linking to other different DB server types)
My reviewed structure needs to be something similar to do this: ( I'm only including a couple of things for this example)
Template Entity has TemplateName as VO.
The TemplateName must satisfy 2 specs. Has to be more than 3 chars long and has to be unique.
I am using a TemplateRepositoryInterface to check the uniqueness and the interface has an Eloquent implementation bounded in a service provider.
Therefore the Template Entity has a method:
public function create()
{
if ($this->meetsTemplateNameSpecification())
{
//fire events etc... saving to repo is done one step above from a service that call this class and gets $this to send tot he interface
return $this;
}
throw new InvalidArgumentException("Template name is not valid.");
}
Then my meetsTemplateNameSpecification method:
private function meetsTemplateNameSpecification($originalTemplateName = null)
{
$templateNameSpecification = new TemplateNameSpecification($this->name, $originalTemplateName);
if($templateNameSpecification->isMet())
{
return true;
}
return false;
}
Before this restructure, a service was initiating all these and passing the RepositoryInterface to them so that was easy. However, this way I don't know how and /or where to pass or inject the interface because if I have it injected from the container to the Specification class then I cannot initiate from the Entity and I cannot inject the Spec class to the entity either because i want to be able to use it's constructor.
I find it very hard to do in PHP and Active Record with keeping a separation of concerns and not having a dependency on persistence in the domain.
Does anyone have a better structure? Let me know if you need more code please.
So far the only solution that comes to mind is to have static methods in my specification objects so that they do not need to be initiated and I can inject the Repo dependency from the container. Is this the way to go or there's better ways that work with PHP. I hate having to inject from the container to the Domain too but don't think there's any better way unless you're using a different architecture.
I think you're overcomplicating things.
Specification pattern is cool if used in a very general method signature that takes specifications as parameters, or if you have a whole family of specifications. With just one or two particular conditions to test, it might be overkill.
Also, trying to inject a Repository into a domain object (as I guess you are) may be causing you more trouble than good. String length is most probably not a domain rule and uniqueness may not be either. You might be better off checking those constraints at the Application Service (or Controller) level, directly calling the Repository there for uniqueness, which will spare you all the injection trouble.
I have a number of Soap Server classes most of which will need to implement 3 methods:
ping() // something to bounce a signal off to prove it has been reached
getCredentials($creds) // credentials to check sets session value
getCaller() // for logging, uses session value
As they form part of the WSDL defn they need to be public.
I am fairly sure this (I have christened it a Soaplogin) would need to be an abstract class (because it must never be instantiated on its own)
The concrete classes which extend then this core then have their own methods, none of which are shared.
I am searching for the best type of Pattern to use and am getting a bit confused, though I think a Template Method just about fits the bill - but I could just plain extend the SoapLogin class.
What advice can you give me on the best pattern to use, and maybe a preferred name for this class.
(while this uses ZF1 components it does not use full blown MVC - in case that was of importance)
Prefer composition over inheritance.
What you really do is you create completely independent interfaces that only by chance happen to have the same methods.
Fine. Generic methods that always do the same - that should be in a class of it's own. But not ONE class for all these methods! One class per method!
You can then add all these method classes to your server classes, and also add all the special functions the same way.
That way you can combine any of the generic functions in any way, and add another only to one API if needed.
This pattern could be a good solution if you just want to create several soap connect.
An other one could be to use interface. It will tell your program that every class that implements SoapItf (for example, rename it if you want) are able to perform soap method.
If you look for an evolutive application, maybe you'll need to connect with Rest webservice after so you can create an abstract class Werbservice, two class Soap and Rest that extends it and this two class implements interface SoapItf ans RestItf respectively.
This method helps using polymorphism, an important concept in OOP.
In this case I can add method to Soap or Rest without changing both.
After that if you have specificity with Soap like in your example, you could extends Soap class. It will be easier to evolve the application and using package architecture (interesting if you work with namespaces)
In my opinion, you can use template pattern to manage a common resource that is spreadable in sub-classes. For instance, you have a soaplogin common abstract class and that might have some resource that can be used by most of the sub-classes. Then it's better to manage that resource in super-class and pass the callback in subclass to use the resource of the super-class. Advantage is that you are managing resource at a single place.
For example, I have a common resource in my super-class. I can create a callback passing resource as a parameter.
interface ResourceCallback {
T call(Resource resource);
}
Then can define a abstract method in super-class like as doWithResource(ResourceCallback callback) and all the subclass can now use the resource with their own implementation of their methods.
How to solve the problem of composing a Controller class in PHP, which should be:
easily testable by employing Dependency Injection,
provide shared objects for end programmer
provide a way to load new user libraries
Look down, for controller instantiation with a Dependency injection framework
The problem is, that derived Controllers may use whatever resources the programmer wants to (eg. the framework provides). How to create a unified access to shared resources (DB, User, Storage, Cache, Helpers), user defined Classes or another libraries?
Elegant solution?
There are several possible solutions to my problem, but neither one looks to be a elegant
Try to pass all shared objects by constructor? (may create constructor even with 10 placeholders)
Create getters, settters? (bloated code) $controller->setApplication($app)
Apply singletons on shared resources? User::getInstance() or Database::getInstance()
Use Dependency Injection container as a singleton for object sharing inside the controller?
provide one global application singleton as a factory? (this one looks very used in php frameworks, hovewer it goes strongly against DI principles and Demeter's law)
I understand, that creating strongly coupled classes is discouraged and banished for :), however I don't know how this paradigm applies to a starting point for other programmers (a Controller class), in which they should be able to access shared resources provided to the MVC architecture. I believe, that breaking up the controller class into smaller classes would somehow destroy the practical meaning of MVC.
Dependency Injection Framework
DI Framework looks like a viable choice. However the problem still persists. A class like Controller does not reside in the Application layer, but in the RequestHandler/Response layer.
How should this layer instantiate the controller?
pass the DI injector into this layer?
DI Framework as a singleton?
put isolated DI framework config only for this layer and create separate DI injector instance?
Are you developing a framework yourself? If not, your question does not apply, because you have to choose from already existing frameworks and their existing solutions. In this case your question must be reformulated like "how do I do unit testing/dependency injection in framework X".
If you are developing a framework on you own, you should check first how already existing ones approach this issue. And you must also elaborate your own requirements, and then just go with the simplest possible solution. Without requirements, your question is purely aesthetic and argumentative.
In my humble opinion the simplest solution is to have public properties which initialize to defaults provided by your framework, otherwise you can inject your mocks here. (This equals to your getters/setters solution, but without the mentioned bloat. You do not always need getters and setters.) Optionally, if you really need it, you may provide a constructor to initialize those in one call (as you suggested).
Singletons are an elegant solution, but again, you must ask yourself, is it applicable in your case? If you have to have different instances of the same type of object in your application, you can't go with it (e.g. if you wish to mock a class only in half of your app).
Of course it is really awesome to have all the options. You can have getters/setter, constructors, and when initialization is omitted, default are taken from a singleton factory. But having too many options when not needed, is not awesome, it is disturbing as the programmer has to figure out which convention, option and pattern to use. I definitely do not want to make dozens of design decisions just to get a simple CRUD running.
If you look at other frameworks you will see that there is no silver bullet. Often a single framework utilizes different techniques depending on the context. In controllers, DI is a really straightforward thing, look at CakePHP's $helpers, $components variables, which instruct to inject appropriate variables into the controller class. For the application itself a singleton is still a good thing, as there is always just a single application. Properties less often changed/mocked are injected utilizing public properties.
In case of an MVC, subclassing is perfectly viable option as well: just as AppController, AppView, AppModel in CakePHP. They are inserted into the class hierarchy between the frameworks's and all your particular Controller, View and Model classes. This way you have a single point to declare globals for your main type of classes.
In Java, because of dynamic class loaders and reflection, you have even much more options to choose from. But on the other hand, you have to support much more requirements as well: parallel requests, shared objects and states between worker threads, distributed app servers etc.
You can only answer the question what is right for you, if you know what you need in the first place. But actually, why do you write just another new framework anyway?
Singletons are frowned upon when Dependency Injection is viable (and I have yet to find a case where a Singleton was necessary).
More than likely you will have control of instantiation of controllers, so you can get away with the mentioned $controller->setApplication($application), but if necessary you can use static methods and variables (which are far less harmful to the orthogonality of an application than Singletons); namely Controller::setApplication(), and access the static variables through the instance methods.
eg:
// defining the Application within the controller -- more than likely in the bootstrap
$application = new Application();
Controller::setApplication($application);
// somewhere within the Controller class definition
public function setContentType($contentType)
{
self::$application->setContentType($contentType);
}
I have made of a habit of separating static and instance properties and methods (where necessary, and still grouping properties at the top of the class definition). I feel that this is less unwieldy than having Singletons, as the classes still remain quite compact.
How about refactoring?
Granted that was not one of your options, but you state the code is a largely coupled class. Why not take this time and effort to refactor it to more modular, testable components?
As far as I understand, the Application class of yours should be the dispatcher. If so, I would rather use the controller constructor to pass an instance of the Application, so the controller would know who's invoking it. At later point if you want to have a different Application instance depending on whether the code is invoked from within CLI, you can have an ApplicationInterface which the Application\Http and Application\Cli would implement and everything would be easy to maintain.
You could also implement some factory pattern to get a nice implementation of the DI. For example, check the createThroughReflection method here: https://github.com/troelskn/bucket/blob/master/lib/bucket.inc.php
I hope this makes sense.
Regards,
Nick
You could also use a ControllerFatory in which you would give to your Application or Router/Dispatcher
Sou you could call $controllerFactory->createController($name);
Your Application would have no idea how to create your controllers the Factory would. Since you ca inject your own ControllerFactory in to your DI container you can manage all dependencies you want depending on the controller.
class ControllerFactory {
public function __construct(EvenDispatcher $dispatcher,
Request $request,
ResponseFactory $responseFactory,
ModelFactory $modelFactory,
FormFactory $formFactory) {
...
}
public function createController($name = 'Default') {
switch ($name) {
case 'User':
return new UserController($dispatcher,
$request,
$responseFactory->createResponse('Html'),
$modelFactory->createModel('User'),
$formFactory->createForm('User'),...);
break;
case 'Ajax':
return new AjaxController($dispatcher,
$request,
$responseFactory->createResponse('Json'),
$modelFactory->createModel('User'));
break;
default:
return new DefaultController($dispatcher, $request, $responseFactory->createResponse('Html'));
}
}
}
So you just need to add this factory in your DI container and pass it to your Application.
Whenever you need a new controller you add it to the factory and if new dependencies are required you give them to the factory through your DI container.
class App {
public function __construct(Router $router,Request $request, ControllerFactory $cf, ... ) {
...
}
public function execute() {
$controllerName = $this->router->getMatchedController();
$actionName $this->router->getMatchedAction();
$controller = $cf->createController($controllerName);
if(is_callable($controller, $actionName)) {
$response = $controller->$action(request);
$response->send();
}
}
}
This is not production code, I haven't tested, but this is how you decouple your controllers from your application. Notice here though that there is one bad coupling here because my controller return's a response and I execute the response in the App. But like I said this is just a small example.
It is usually a good idea to pass factories for Models, Forms, and Controllers to their respective parents, because you will end up loading all your object Graph at bootstrap time wich is really bad and memory consuming.
I know this answer was already approved, but it's my 2 cents on the subject
There is a good article on the subject
http://miller.limethinking.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/