mardi 3 décembre 2019

Advice with pattern for laravel project

I'm trying to figure it out the best approach to develop a project that I'm working on (and that have the possibility of growing). Maybe you guys can give some advice, some tips.

On the application, there will be a section to create a contract. At the same time, the app should insert the members of contract, membership cards for each member, a sale (with price) of the contract, a sale comission for the seller, a group of monthly payments. All of this coming from one single form.

I was thinking on let the controllers on the clean side, dividing responsabilities with others layers. The idea until now is explained with some sample codes:

[ContractController.php]

use App\Http\Requests\CreateContractRequest;
use App\Services\CreateContractService;

class ContractController {

    public function create(CreateContractRequest $request, CreateContractService $service) {

        $contract = $service->execute($request->only(
            'cod_plan', 
            'cod_seller',
            'expiration_date',
            'member_list',
            ... other columns ...
        ));

        return response()->json($contract, 201);

    }

}

[CreateContractService.php]

use App\Repositories\ContractRepository;

use App\Services\AddMemberToContractService;
use App\Services\AddMembershipCardToMemberService;
use App\Services\CreateSaleService;

class CreateContractService {

    public function __construct() {

        $this->contractRepo = new ContractRepository();

        $this->addMemberToContract = new AddMemberToContractService();
        $this->addMembershipCardToMember = new AddMembershipCardToMemberService();
        $this->createSale = new CreateSaleService();

    }

    public function execute(array $data) {

        // Create contract
        $new_contract = $this->contractRepo->create($data);

        foreach ($data['member_list'] as $m) :

            // Add members
            $new_member = $this->addMemberToContract->execute($id_contract, $m);

            // Create membership cards for members
            $new_card = $this->addMembershipCardToMember->execute($new_member);

        endforeach;

        // Create sale
        $new_sale = $this->createSale->execute($data);

        ... others inserts ...

        return $new_contract;

    }

}

[ContractRepository.php]

use App\models\Contracts;

class ContractRepository {

    public function create(array $data) {

        $o_contract = new Contracts();
        $o_contract->cod_plan = $data['cod_plan'];
        $o_contract->cod_seller = $data['cod_seller'];

        ... other columns ...

        $o_contract->save();

        return $o_contract;

    }

}

With that, I have some questions.

1) This approach make sense? Is the better way of do it? I'm trying to make the code more reusable and decoupled.

2) Can I (and should I) separate more the services and the logic behind them?

3) How should I handle the errors? Use exceptions? Even for ajax requests? Should I verify for errors on each part of the 'execute' method and return messages mannually?

4) If I have to work with exceptions, how can make my own exceptions?

5) If some part of the code result on a error, how can I undo the inserts already done to make sure that the user can utilize the form to try the same insertion again?

6) On the services, should I only return data objects, booleans or responses?

7) The responses are better just in the controllers?

8) How should I handle errors on the repositories and pass the same errors to the services?

9) With this structure, can I make tests more easily?

10) Its hard to use the same code to a web and a api version of the app?

I appreciate the help.

(Sorry if the english is not that good...)

Aucun commentaire:

Enregistrer un commentaire