Xác nhận được xác định trong lớp nào?


18

Tôi đang tạo API nghỉ ngơi bằng Spring Boot và tôi đang sử dụng Xác thực Hibernate để xác thực các yêu cầu đầu vào.

Nhưng tôi cũng cần các loại xác nhận khác, ví dụ như khi cập nhật dữ liệu cần kiểm tra, nếu id công ty không tồn tại, tôi muốn đưa ra một ngoại lệ tùy chỉnh.

Xác nhận này nên được đặt ở lớp dịch vụ hay lớp điều khiển?

Lớp dịch vụ:

 public Company update(Company entity) {
    if (entity.getId() == null || repository.findOne(entity.getId()) == null) {
        throw new ResourceNotFoundException("can not update un existence data with id : " 
            + entity.getId());
    }
    return repository.saveAndFlush(entity);
}

Lớp điều khiển:

public HttpEntity<CompanyResource> update(@Valid @RequestBody Company companyRequest) {
    Company company = companyService.getById(companyRequest.getId());
    Precondition.checkDataFound(company, 
        "Can't not find data with id : " + companyRequest.getId());

    // TODO : extract ignore properties to constant

    BeanUtils.copyProperties(companyRequest, company, "createdBy", "createdDate",
            "updatedBy", "updatedDate", "version", "markForDelete");
    Company updatedCompany = companyService.update(company);
    CompanyResource companyResource = companyAssembler.toResource(updatedCompany);
    return new ResponseEntity<CompanyResource>(companyResource, HttpStatus.OK);
}

Câu trả lời:


8

Cả lớp điều khiển và lớp dịch vụ đều phơi bày một số giao diện nhất định. Các giao diện xác định hợp đồng về cách sử dụng giao diện. Hợp đồng thường có nghĩa là những đối số (và loại và giá trị của nó) được mong đợi, ngoại lệ nào có thể được ném, tác dụng phụ nào được tạo ra, v.v.

Bây giờ, xác thực của bạn về cơ bản là thực thi hợp đồng của phương thức update update () và phương thức update () của lớp dịch vụ. Cả hai đều có hợp đồng rất giống nhau nên sẽ rất tự nhiên nếu việc xác nhận (thực thi hợp đồng) cũng sẽ phổ biến.

Một cách có thể để làm điều đó là tách biệt việc xác nhận hợp đồng này và gọi nó trong cả hai lớp. Điều này thường rõ ràng nhất - mỗi lớp / phương thức thực thi hợp đồng riêng của họ, nhưng thường không thực tế vì hiệu suất (truy cập cơ sở dữ liệu) hoặc các lý do khác.

Khả năng khác là ủy quyền xác thực này cho lớp dịch vụ trong khi xác định rõ hành vi trong trường hợp xác thực không thành công trong hợp đồng lớp dịch vụ. Lớp dịch vụ thường trả về một số lỗi xác thực chung (hoặc ném ngoại lệ) và lớp trình điều khiển sẽ muốn phản ứng theo một cách cụ thể nào đó đối với lỗi - trong trường hợp này, chúng tôi sẽ trả lại 400 yêu cầu xấu để báo hiệu, yêu cầu đến không hợp lệ.

Trong thiết kế này, có một mối nguy hiểm về sự kết hợp quá nhiều giữa logic nghiệp vụ trong lớp dịch vụ (nên khá chung chung) và bộ điều khiển (xử lý logic tích hợp).

Dù sao, đây là câu hỏi khá gây tranh cãi và 100 người sẽ trả lời với 100 câu trả lời. Đây chỉ là của tôi về nó.


1

Đầu vào phải được kiểm tra trong lớp dịch vụ.

Và "Không thể tìm thấy id" là điều kiện lỗi logic. Vì vậy, nên được ném từ lớp điều khiển.

Điều này một lần nữa phụ thuộc vào lớp / thiết kế của bạn.
Những gì một lớp dịch vụ phải làm và những gì được mong đợi từ lớp điều khiển.


Một câu trả lời không nên tìm kiếm làm rõ thêm từ câu hỏi. Nếu câu hỏi cần làm rõ, nó nên được bình luận và có thể được gắn cờ để đóng nếu quá không rõ ràng. Vâng, tôi nhận ra rằng bạn không có tiếng tăm cho một trong những hành động đó.

"Kiểm tra đầu vào" là mơ hồ. Ví dụ: tôi có thể đặt một thuộc tính Bắt buộc trên một trường để cho biết rằng nó phải được điền vào, nhưng tôi cũng có thể đặt một thuộc tính tùy chỉnh phức tạp để kiểm tra, ví dụ: một giá trị trường lớn hơn một trường khác. IMHO, so sánh xác thực "ngửi" nhiều hơn lớp dịch vụ kinh doanh so với lớp điều khiển.
JustAMartin

1

Xác nhận ngủ đông là kiểm tra tính toàn vẹn của dữ liệu. Để tránh RuntimeExceptions từ bbdd. Chúng có khá nhiều xác nhận giống như bạn nên kiểm soát với các ràng buộc . Bởi vì chỉ có lớp kinh doanh nên được cho ăn lớp kiên trì, nên bạn có thể (hoặc không, tùy thuộc vào bạn) tin tưởng vào tính đúng đắn của dữ liệu xuất phát từ lớp doanh nghiệp của bạn

Tôi không đặt xác nhận trong DAO. Tôi mong đợi dữ liệu hợp lệ từ các lớp trên. Trong trường hợp có lỗi, tôi ủy quyền cho bbdd có trách nhiệm nhận thức được nội dung của nó.

Sau đó đến xác nhận ở lớp kinh doanh. Tất cả các xác nhận kinh doanh tập trung vào việc giữ sự gắn kết của dữ liệu, chứ không phải tính toàn vẹn của dữ liệu .

Cuối cùng tôi thực hiện xác nhận trước đó trên lớp điều khiển. Những người chỉ liên quan với lớp như vậy.

Bạn sẽ sớm thấy các xác nhận được dự định sẽ được thực hiện ở tầng doanh nghiệp. Phổ biến nhất: kiểm soát id. Điều này có thể dễ dàng được thực hiện ở cả hai lớp. Nếu bạn mong đợi có nhiều bộ điều khiển hoặc khách hàng tiêu thụ lớp doanh nghiệp của mình thì thay vì lặp lại xác nhận tương tự ở mọi nơi, nó sẽ là một ứng cử viên xuất sắc được đưa vào lớp doanh nghiệp.

Đôi khi các bộ điều khiển có các quy tắc và điều kiện riêng sẽ không được sao chép ở bất kỳ mặt tiền nào khác. Sau đó, nó là một ứng cử viên được đưa vào một bộ điều khiển như vậy.

Hãy suy nghĩ về những gì bạn đang xác nhận và nếu bạn muốn áp dụng nó cho tất cả mọi người không có vấn đề gì. Hoặc nếu đó là xác thực theo ngữ cảnh ("Tôi xác thực một cái gì đó chỉ xảy ra ở một mặt tiền kiểm soát / xem cụ thể).


0

Trong cửa hàng Java của chúng tôi, chúng tôi đã cố tình phân tách xác thực tiện ích web thành ba hoạt động riêng biệt.

  1. Định dạng cơ bản - số phải là số; ngày phải là ngày hợp lệ, v.v. Thông thường, việc xác thực này được cung cấp miễn phí - khung web sẽ thực hiện điều đó cho bạn khi ràng buộc nội dung widget với mô hình.
  2. Xác nhận widget đơn - ngày phải trong quá khứ; một số nguyên phải nằm trong khoảng từ 1 đến 100; customerId phải tồn tại trong cơ sở dữ liệu, v.v. Điều này thuộc về lớp điều khiển trong hầu hết các trường hợp, nhưng có thể cần hỗ trợ từ kho lưu trữ dữ liệu.
  3. Xác thực tiện ích chéo - ngày thanh toán phải sau ngày đăng ký; ngày chết không thể là trước ngày sinh, v.v ... Đây chắc chắn là xác nhận quy tắc kinh doanh. Chúng tôi cũng có xu hướng đặt cái này trong lớp điều khiển, nhưng bạn có thể muốn chuyển nó thành một trình xác nhận nghiệp vụ để nó có thể được sử dụng lại.

Nếu lớp 1 không thành công, chúng tôi không kiểm tra 2 hoặc 3. Tương tự nếu 1 thành công và 2 không thành công, chúng tôi không làm 3. Điều này ngăn các thông báo lỗi giả được tạo.

Bạn đang hỏi về các giá trị trong một cuộc gọi REST thay vì nội dung widget, nhưng các nguyên tắc tương tự được áp dụng.


-1

Thử nghiệm điều khiển aproach chiếu sáng điều này ,, sau khi tất cả không có bộ điều khiển và bạn phải chọn một tùy chọn khác. Rõ ràng các quy tắc của bussines nên ở một nơi, và đây là một hạn chế khác trong quyết định của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.