Friday, April 14, 2017

Laravel Service as Controller - working with multiples controllers

I'am a Brazilian developer, so... sorry for my limited English right away.

Well, in fact my problem is more a convention problem because until now I hadn't use services with Laravel (my apps were that simple so far).

I read about it before ask this question, but nothing helped with this specific situation. I'll try to describe in a objective way.

before that, just a comment: I know about the mistake using just controllers in these example. The ask is really about that mistake.

Well, the actual structure is:

abstract class CRUDController extends Controller {

    protected function __construct($data, $validatorData) {
        // store the data in a attribute
        // create with Validator facade the validation and store too
    }

    abstract protected function createRecord();

    protected function create() {
        try {
            // do the validation and return an Response instance with error messages
            // if the data is ok, store in the database with models
            // (here's where the magic takes place) in that store!
            // to do that, calls the method createRecord (which is abstract)
            $this->createRecord();
            // return a success message in an Response instance
        }
        catch(\Exception $e) {
            // return an Response instance with error messages
        }
    }

}

class UserController extends CRUDController {

    public function __construct($data) {
        parent::__construct($data, [
            'rules' => [
                 // specific user code here
             ],
            'messages' => [
                 // specific user code here
             ],
            'customAttributes' => [
                 // specific user code here
             ]
        ]);
    }

    protected function createRecord() {
        $user = new UserModel();
        // store values here...
        $user->save();
        return $user;
    }

}

// here's the route to consider in that example
Route::post('/user', 'WebsiteController@register');

class WebsiteController extends Controller {

    private $request;

    public function __construct(Request $request) {
        $this->request = $request;
    }

    public function register() {
        $user = new UserController();
        $user->create($this->request);
        // here's the problem: controller working with another controller
    }

}

class UserAPIController extends Controller {
    // use here the UserController too
}

and many other classes that extends CRUDController in the same way...

What I want

I want to create a controller (called here as CRUDController) to reuse methods like the pattern says (create, read, update and delete). To be really objective here I'll use the create method as an example. With the code above it seems clear the purpose? I think so... all my controllers have that code of validation equal and reusable. That's the thing. Besides that, I want to my route of website call another controller (UserController) to store new users... but in the same way, I'll create an API that uses the same controller in the same way (with validations etc). That's the purpose of Responses in the CRUDController (I'll read them in the WebSiteController to resolve what to do, like show a view and in the other hand with the API I'll basically return the Response.

My real problem

Convention and pattern. The MVC pattern is broken here. Controller calling another controller is wrong and I know that. I want to know what thing I should use! Services? Is that right? I see a lot (really) of examples of services but nothing like that, working with models and reusing code, etc. I never use Services but I know how to use, but I don't know if it's right to these cases.

I really hope that someone can help here and sorry once again for the mistakes with the English. Thanks a lot.



via NapoleĆ£o Wingert

Advertisement