Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should Service Layer methods expect instances or id's?

This question arised from my work on a Grails application, but it applies to pretty much every web application developed in layers. Here's a simple example:

class OrderService {

    // Option 1
    def shipOrder(Order order) {
        order.status = OrderStatus.SHIPPED
        emailService.sendShipmentEmail(order)
        // ...
    }

    // Option 2
    def shipOrder(long orderId) {
        def order = Order.get(orderId)
        order.status = OrderStatus.SHIPPED
        emailService.sendShipmentEmail(order)
        // ...
    }

}

Is any of these options documented as being better than the other one?

like image 262
André Willik Valenti Avatar asked Jul 03 '13 18:07

André Willik Valenti


People also ask

How does a service layer work?

Service Layer is an abstraction over domain logic. It defines application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation.

What is the difference between service layer and controller layer?

In our analogy, the controller is the manager, while the service is the worker. If you think about what the manager's role is, he/she typically: manages the incoming work requests. decides which worker should do the work.

What is the purpose of service layer in Java?

The service layer consists of a collection of Java classes that implement business logic (data retrieval, updates, deletions, and so on) through one or more high-level methods. In other words, the service layer controls the workflow.


1 Answers

I tend to prefer ids, since you sometimes want to use pessimistic locking, and then it's easy to change Order.get(orderId) to Order.lock(orderId). Locking has to happen in a transaction, so using the first approach you'd lock after reading, running the small risk of update in-between.

Sometimes it's necessary to load the instance outside of the service, e.g. to test for existence in the controller, so the second approach can feel like it wastes a database call. But you can change the get() call to an exists() call and only check for the existence of the id, rather than loading the entire instance just to see if it's there.

Note that you should use long orderId in your method signature since allowing a null id doesn't make sense.

like image 121
Burt Beckwith Avatar answered Sep 27 '22 21:09

Burt Beckwith