Modular PHP Monolith: Cooking Recipe

The article was written based on my report at the meetup . In it, I tell the story of how we took and did not cut the monolith into microservices, and what we did instead.





, 2009 . 2018 big ball of mud ( ), , «-», :) , . :





  • , .





  • . - , , , .





  • , , . 2018 2009 ... 





  • , , .





2018 - , , . - , , . .





() — - , , . , golang . , devops , . ( ) , . , big ball of mud, .





:





  • ;





  • ;





  • ;





  • .





- , . , , , .





, .





. Domain-Driven Design. 

- (Domain-Driven Design). 





Domain-Driven Design , . , . , e-commerce : customer, product catalog, ordering, shipping. . namespace'. , - , .





Domain-Driven Design Eric Evans «Domain-Driven Design: Tackling Complexity in the Heart of Software»  Vaughn Vernon «Implementing Domain-Driven Design».





, - . « » ( « . »), : domain, application, infrustructure.





, , . , . Application Logic — , , . , « », « ». , . . (view models), , , . , - - . . , - - .





, :





  • ;





  • , ;





  • — ;









(Dependency Rule) — . (dependency inversion). - , , , . - . , , , dependency injection, , , . 





, - :





  • UI

















, . — , . - .





:





, . , Common, , .





. Anti-corruption Layer. 

, , Anti-corruption Layer. «Domain-Driven Design»:





Create an isolating layer to provide clients with functionality in terms of their own domain model. The layer talks to the other system through its existing interface, requiring little or no modification to the other system. Internally, the layer translates in both directions as necessary between the two models.





ACL , API , , . 





, Ordering Shipping. ids . Ordering API, . , DTO API Shipping. DTO , . , . Shipping , , , , , . . . , , , .





.





Api, OrderInfo, ApiInterface ApiInterface. 





Adapter. , . . 





: , . . , , , . , «» API , .





, , . CQRS.





. API Gateways.

API , , UI. API Gateway, API. , API Gateway , . 





, PHP . , . deptrac . composer . CI/CD, , , , .





: depfile-layers.yaml, , depfile-modules.yaml, . , : 





  • Domain ;





  • Application Domain;





  • API  Domain Application;





  • Infrastructure . 





depfile-layers.yaml





paths:
  - ./src
  - ./vendor

exclude_files: ~

layers:
  - name: Domain
    collectors:
      - type: directory
        regex: /src/\w+/Domain/.*
  - name: Application
    collectors:
      - type: directory
        regex: /src/\w+/Application/.*
  - name: Api
    collectors:
      - type: directory
        regex: /src/\w+/Api/.*
  - name: Infrastructure
    collectors:
      - type: bool
        must:
          - type: directory
            regex: /src/\w+/Infrastructure/.*
  - name: Vendor
    collectors:
      - type: directory
        regex: /vendor/.*

ruleset:
  Domain:
  Application:
    - Domain
  Api:
    - Domain
    - Application
  Infrastructure:
    - Domain
    - Application
    - Api
    - Vendor
      
      



, deptrac , «». , , . Adapter, , . 





depfile-modules.yaml





paths:
  - ./src
exclude_files:
  - .\/src\/.*\/Infrastructure\/Adapter\/.*
layers:
  - name: Customer
    collectors:
      - type: directory
        regex: /src/Module/Customer/.*
  - name: Ordering
    collectors:
      - type: directory
        regex: /src/Module/Ordering/.*
  - name: Shipping
    collectors:
      - type: directory
        regex: /src/Module/Shipping/.*
ruleset: ~
      
      



. Event-Driven Design.

, , . -. 





, , , , , ; , . .









- . , , , . , , , . , , . , . . 





, , , . , . 





, . , ( , ..) , . 





. , weak-schema serialization, , json, xml. .





, OrderPlaced





class OrderPlaced implements DomainEventInterface
{
    private const TYPE = 'order.order_placed';
    // ...

    public function __construct(string $orderId, Customer $customer, Products $products, float $total)
    {
        $this->orderId = $orderId;
        $this->customer = $customer;
        $this->products = $products;
        $this->total = $total;
    }

}
      
      



json:





{
  "orderId": 874,
  "customer": {
    "id": 87058,
    "name": "John Doe",
    "postalCode": "EC1-001",
    "age": 35,
    "status": "gold"
  },
  "products": [
    {
      "id": 84039,
      "name": "ice cream"
    },
    {
      "id": 1908,
      "name": "burger"
    }
  ],
  "total": 17.95
}
      
      



, . , big ball of mud:





  • DDD;





  • ;





  • ;





  • ;





  • - ;





  • ;





  • deptrac.





?





  • ;





  • , , , ;





  • ;









, Sander Mac. , . . .





Image source: https://twitter.com/Sander_Mak/status/852459340493709313
: https://twitter.com/Sander_Mak/status/852459340493709313

:





If you can't build a monolith, what makes you think microservices are the answer?





P.S.

PHP- 24 2021 ( PHP Point) « , », .








All Articles