4 added 32 characters in body
source | link
// OrderController

protected $orderRepository;

public function findOrder( int $orderId ) : ActionResult
{
     $order = $this->orderRepository->find($orderId);

     return $this->view('order', $order);
}
// OrderController

protected $orderService;

public function findOrder( int $orderId ) : ActionResult
{
    $order = $this->orderSerivce->find($orderId);

    return $this->view('order', $order);
}
// OrderController

protected $orderRepository;

findOrder( int $orderId ) : ActionResult
{
     $order = $this->orderRepository->find($orderId);

     return $this->view('order', $order);
}
// OrderController

protected $orderService;

findOrder( int $orderId ) : ActionResult
{
    $order = $this->orderSerivce->find($orderId);

    return $this->view('order', $order);
}
// OrderController

protected $orderRepository;

public function findOrder( int $orderId ) : ActionResult
{
     $order = $this->orderRepository->find($orderId);

     return $this->view('order', $order);
}
// OrderController

protected $orderService;

public function findOrder( int $orderId ) : ActionResult
{
    $order = $this->orderSerivce->find($orderId);

    return $this->view('order', $order);
}
3 deleted 1 character in body
source | link

First and foremost there is always going to be some level of coupling between your client and the API. Although, the goal of dividing your application into distinct conceptual layers (e.g. ViewView -> ApplicationApplication -> DomainDomain -> PersistencePersistence) is to foster decoupling in a way that each can change independently of one another, these layers still must communicate. That is, at the boundary between layers, there must exist some shared knowledge in terms of communication (not implementation).

For example, your View layer must know how to compose a valid command for your Application layer (or at the very least know how to ask how to compose a command). What this means is that if you ever change the command signature (the data thethat must be included with a request) or the query signature (the data returned by a request) in your Application layer, it's likely this change will bubble up to your View layer. This applies to all architectural boundaries and is often the best place to use interfaces to clearly illustrate the communication contract.

Now, this may seem like just a silly semantic difference where I've only just re-named a single variable, but it illustrates a fundamental and very important concept. Your Controllers are really part of your UIView, not your Application layer. The first example has dependency between the Controller and the Domain via the OrderRepository (making the Controller part of the Application layer), where the second example has the dependency on the Application via OrderService instead (keeping the Controller in the View).

First and foremost there is always going to be some level of coupling between your client and the API. Although, the goal of dividing your application into distinct conceptual layers (e.g. View -> Application -> Domain -> Persistence) is to foster decoupling in a way that each can change independently of one another, these layers still must communicate. That is, at the boundary between layers, there must exist some shared knowledge in terms of communication (not implementation).

For example, your View layer must know how to compose a valid command for your Application layer (or at the very least know how to ask how to compose a command). What this means is that if you ever change the command signature (the data the must be included with a request) or the query signature (the data returned by a request) in your Application layer, it's likely this change will bubble up to your View layer. This applies to all architectural boundaries and is often the best place to use interfaces to clearly illustrate the communication contract.

Now, this may seem like just a silly semantic difference where I've only just re-named a single variable, but it illustrates a fundamental and very important concept. Your Controllers are really part of your UI, not your Application layer. The first example has dependency between the Controller and the Domain (making the Controller part of the Application layer, where the second example has the dependency on the Application instead (keeping the Controller in the View).

First and foremost there is always going to be some level of coupling between your client and the API. Although the goal of dividing your application into distinct conceptual layers (e.g. View -> Application -> Domain -> Persistence) is to foster decoupling in a way that each can change independently of one another, these layers still must communicate. That is, at the boundary between layers, there must exist some shared knowledge in terms of communication (not implementation).

For example, your View layer must know how to compose a valid command for your Application layer (or at the very least know how to ask how to compose a command). What this means is that if you ever change the command signature (the data that must be included with a request) or the query signature (the data returned by a request) in your Application layer, it's likely this change will bubble up to your View layer. This applies to all architectural boundaries and is often the best place to use interfaces to clearly illustrate the communication contract.

Now, this may seem like just a silly semantic difference where I've only just re-named a single variable, but it illustrates a fundamental and very important concept. Your Controllers are really part of your View, not your Application layer. The first example has dependency between the Controller and the Domain via the OrderRepository (making the Controller part of the Application layer), where the second example has the dependency on the Application via OrderService instead (keeping the Controller in the View).

    Post Undeleted by king-side-slide
2 added 3326 characters in body
source | link

First and foremost there is always going to be some level of coupling between your client and the API. Although, the goal of dividing your application into distinct conceptual layers (e.g. View -> Application -> Domain -> Persistence) is to foster decoupling in a way that each can change independently of one another, these layers still must communicate. That is, at the boundary between layers, there must exist some shared knowledge in terms of communication (not implementation).

For example, your View layer must know how to compose a valid command for your Application layer (or at the very least know how to ask how to compose a command). What this means is that if you ever change the command signature (the data the must be included with a request) or the query signature (the data returned by a request) in your Application layer, it's likely this change will bubble up to your `ViewView layer. This applies to all architectural boundaries and is often the best place to use interfaces to clearly illustrate the communication contract.

The second consideration (of which is the most concern to me) is that an application should not require HTTP to communicate with itself. In fact, a properly designed application should not even be "aware" of the web in general. This makes sense right? The entire point of layering your application with a View as the highest conceptual layer is to enable the "swapping" of the View without needing to change any of the layers beneath it! This affords the existence of many independent Views of your application (console, HTML, JSON, desktop, etc).

Okay, so how does all of that relate to your question? I think the issue we are running into here for your application is that you have defined the contract for communication between layers only in terms of HTTP. That is, there doesn't exists an application-level form of communication. For example, instead of translating an HttpRequest into a more direct command (e.g. FindOrder), you may be using the HttpRequest as the command directly. What this ends up doing is pushing application logic "upward" in a way that your Controller methods are responsible for "carrying-out" the command instead of your domain, thereby resulting in the "code coupling" you mention above. For example:

// OrderController

protected $orderRepository;

findOrder( int $orderId ) : ActionResult
{
     $order = $this->orderRepository->find($orderId);

     return $this->view('order', $order);
}

vs.

// OrderController

protected $orderService;

findOrder( int $orderId ) : ActionResult
{
    $order = $this->orderSerivce->find($orderId);

    return $this->view('order', $order);
}

Now, this may seem like just a silly semantic difference where I've only just re-named a single variable, but it illustrates a fundamental and very important concept. Your Controllers are really part of your UI, not your Application layer. The first example has dependency between the Controller and the Domain (making the Controller part of the Application layer, where the second example has the dependency on the Application instead (keeping the Controller in the View).

By pushing the implementation of finding an Order "downward" into an application service, we are achieving decoupling. The View layer is only dependent on the IOrderService interface. This interface exists at a conceptually lower level than your Controllers and can be utilized by any number of components (e.g. a method that return the Order in HTML and a method that returns the Order in JSON).

The important take-away of the above is that the contract (interface) for communication between your conceptual layers should be defined in your application. This facilitates re-use between Views.

My assumption is that, on page load, you would like to render as mush as possible server-side, but don't have an Application layer that helps facilitate different Views in a way that prevents code duplication or coupling between Controllers. Re-organizing your application can serve as the solution.

First and foremost there is always going to be some level of coupling between your client and the API. Although, the goal of dividing your application into distinct layers (e.g. View -> Application -> Domain -> Persistence) is to foster decoupling in a way that each can change independently of one another, these layers still must communicate. That is, at the boundary between layers, there must exist some shared knowledge in terms of communication (not implementation).

For example, your View layer must know how to compose a valid command for your Application layer (or at the very least know how to ask how to compose a command). What this means is that if you ever change the command signature (the data the must be included with a request) or the query signature (the data returned by a request) in your Application layer, it's likely your `View

First and foremost there is always going to be some level of coupling between your client and the API. Although, the goal of dividing your application into distinct conceptual layers (e.g. View -> Application -> Domain -> Persistence) is to foster decoupling in a way that each can change independently of one another, these layers still must communicate. That is, at the boundary between layers, there must exist some shared knowledge in terms of communication (not implementation).

For example, your View layer must know how to compose a valid command for your Application layer (or at the very least know how to ask how to compose a command). What this means is that if you ever change the command signature (the data the must be included with a request) or the query signature (the data returned by a request) in your Application layer, it's likely this change will bubble up to your View layer. This applies to all architectural boundaries and is often the best place to use interfaces to clearly illustrate the communication contract.

The second consideration (of which is the most concern to me) is that an application should not require HTTP to communicate with itself. In fact, a properly designed application should not even be "aware" of the web in general. This makes sense right? The entire point of layering your application with a View as the highest conceptual layer is to enable the "swapping" of the View without needing to change any of the layers beneath it! This affords the existence of many independent Views of your application (console, HTML, JSON, desktop, etc).

Okay, so how does all of that relate to your question? I think the issue we are running into here for your application is that you have defined the contract for communication between layers only in terms of HTTP. That is, there doesn't exists an application-level form of communication. For example, instead of translating an HttpRequest into a more direct command (e.g. FindOrder), you may be using the HttpRequest as the command directly. What this ends up doing is pushing application logic "upward" in a way that your Controller methods are responsible for "carrying-out" the command instead of your domain, thereby resulting in the "code coupling" you mention above. For example:

// OrderController

protected $orderRepository;

findOrder( int $orderId ) : ActionResult
{
     $order = $this->orderRepository->find($orderId);

     return $this->view('order', $order);
}

vs.

// OrderController

protected $orderService;

findOrder( int $orderId ) : ActionResult
{
    $order = $this->orderSerivce->find($orderId);

    return $this->view('order', $order);
}

Now, this may seem like just a silly semantic difference where I've only just re-named a single variable, but it illustrates a fundamental and very important concept. Your Controllers are really part of your UI, not your Application layer. The first example has dependency between the Controller and the Domain (making the Controller part of the Application layer, where the second example has the dependency on the Application instead (keeping the Controller in the View).

By pushing the implementation of finding an Order "downward" into an application service, we are achieving decoupling. The View layer is only dependent on the IOrderService interface. This interface exists at a conceptually lower level than your Controllers and can be utilized by any number of components (e.g. a method that return the Order in HTML and a method that returns the Order in JSON).

The important take-away of the above is that the contract (interface) for communication between your conceptual layers should be defined in your application. This facilitates re-use between Views.

My assumption is that, on page load, you would like to render as mush as possible server-side, but don't have an Application layer that helps facilitate different Views in a way that prevents code duplication or coupling between Controllers. Re-organizing your application can serve as the solution.

    Post Deleted by king-side-slide
1
source | link