inklabs / kommerce-core

PHP shopping cart core platform
https://kommerce-laravel-demo.jamieisaacs.com/
Apache License 2.0
65 stars 14 forks source link

Queries are too complex #88

Closed pdt256 closed 7 years ago

pdt256 commented 7 years ago

Do you have any ideas how to reduce the complexity?

The current way to get a ProductDTO:

try {
    $request = new GetProductRequest($productId);
    $response = new GetProductResponse($this->getPricing());
    $this->dispatchQuery(new GetProductQuery($request, $response));
} catch (EntityNotFoundException $e) {
    return abort(404);
}

$productDTO = $response->getProductDTO();

The classes required to satisfy the request:

GetProductQuery GetProductRequest GetProductResponseInterface GetProductResponse GetProductHandler

The GetProductHandler defers to the ProductService:

class GetProductHandler {
    public function handle(GetProductQuery $query)
    {
        $product = $this->productService->findOneById(
            $query->getRequest()->getProductId()
        );
    }

The ProductService defers to the ProductRepository:

class ProductService {
    public function findOneById(UuidInterface $id)
    {
         return $this->productRepository->findOneById($id);
    }

The ProductRepository defers to the Doctrine EntityRepository:

class ProductRepository {
    public function findOneById(UuidInterface $id)
    {
        return $this->returnOrThrowNotFoundException(
            parent::findOneBy(['id' => $id])
        );
    }
pdt256 commented 7 years ago

Commands are much less complex:

$tagId = $request->input('tagId');
$productId = $request->input('productId');

try {
    $this->dispatch(new AddTagToProductCommand(
        $productId,
        $tagId
    ));

    $this->flashSuccess('Successfully added product');
} catch (KommerceException $e) {
    $this->flashError('Unable to add product');
}

Classes required:

AddTagToProductCommand AddTagToProductHandler

pdt256 commented 7 years ago

Before:

    public function index(Request $httpRequest)
    {
        $queryString = $httpRequest->query('q');

        $request = new ListWarehousesRequest(
            $queryString,
            $this->getPaginationDTO(20)
        );

        $response = new ListWarehousesResponse();
        $this->dispatchQuery(new ListWarehousesQuery($request, $response));

        $warehouses = $response->getWarehouseDTOs();
        $pagination = $response->getPaginationDTO();

        return $this->renderTemplate(
            '@admin/inventory/warehouse/index.twig',
            [
                'warehouses' => $warehouses,
                'pagination' => $pagination,
                'queryString' => $queryString,
            ]
        );
    }

After:

    public function index(Request $httpRequest)
    {
        $queryString = $httpRequest->query('q');

        /** @var ListWarehousesResponse $response */
        $response = $this->dispatchQuery(new ListWarehousesQuery(
            $queryString,
            $this->getPaginationDTO(20)
        ));

        $warehouses = $response->getWarehouseDTOs();
        $pagination = $response->getPaginationDTO();

        return $this->renderTemplate(
            '@admin/inventory/warehouse/index.twig',
            [
                'warehouses' => $warehouses,
                'pagination' => $pagination,
                'queryString' => $queryString,
            ]
        );
    }
pdt256 commented 7 years ago

37 to refactor:

$ find . -name *Query.php

pdt256 commented 7 years ago

Refactoring is really easy. Around 3 minutes per Query:

IMAGE ALT TEXT

Code from the video: https://github.com/inklabs/kommerce-core/commit/66ddaf1f5876d713e21765f55e52e8ea4fa9ec7a

pdt256 commented 7 years ago

Merged to master via #110