简体   繁体   中英

Optional vs exceptions, controllers vs services

I have JAVA design considerations: I'm struggling between choosing:

  1. services return Optional values and controllers handling the non-present case
  2. services handling directly the non-present case, return the real object if present and throw exceptions if not

Are there good practices to help me chose between the 2 approaches?

eg. Option 1 Controller:

public ResponseEntity<Product> findProductById(@PathVariable Long productId) {
        return this.productService.getProductById(productId).map(
                p -> ResponseEntity.ok(p)
        ).orElseThrow(() -> new ResourceNotFoundException(ResourceType.PRODUCT, "Id", productId.toString()));
    }

Service:

    public Optional<Product> getProductById(Long id) {
        return productRepository.findById(id).map(
                product -> someLogic(product)
        );
    }

Option 2: Controller

    public ResponseEntity<Product> findProductById(@PathVariable Long productId) {
        return ResponseEntity.ok(productService.getProductById(productId));
    }

Service

    public Product getProductById(Long id) {
        return productRepository.findById(id).map(
                product -> lazyLoadProduct(product)
        ).orElseThrow(() -> new ResourceNotFoundException(ResourceType.PRODUCT, "Id", id.toString()));;
    }

For both of these approaches, I have a ControllerAdvice which would eventually transform this Exception in a corresponding end-user-friendly message. So they both "work the same"

Exceptions should only be thrown when there is an unexpected event or circumstance that needs to be handled separately from the core business logic. When searching for a resource, the event in which that resource is not found is an expected outcome and therefore not exceptional.

As such, it is my opinion that you should go with neither of these approaches and instead code your controller to be able to handle the returned value of a "not-found" response. (Whether this is an empty list, a special object type, or simply null depends on which your implementation could most easily support.)

I would go for the service approach as this will give you more flexibility. There are cases when you need to manipulate response coming from database and apply workarounds. You can apply this logic in service part.

Prefer 2, Handling empty values is part of business logic and should be handle in service,

Such method can be reusable in other places in your application

Also use Optional only in specific cases when necessary

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM