Ngoại lệ trong ứng dụng API Rails sử dụng Grape với đối tượng dịch vụ tái cấu trúc

Tram Ho

Tóm tắt

Các bước thực hiện refactoring Services Object trong API Rails APP viết bằng Grape

  • Tạo service
  • Xử lý exception, bắt lỗi
  • Sử dụng service vào API

Nội dung

Sau khi hoàn thiện API bằng gem Grape thì mình đã refactor lại code với Service Object, tuy nhiên mình đã gặp một số vấn đề xử lý exception.
Dưới đây là đoạn code của mình trước khi refactor, mình có 2 API: sendactivationemailactivate.

Đi refactor lại code

Tiếp theo mình tiến hành chia nhỏ các đoạn code trong API thành các Service để call lại. Mình tạo một thư mục services trong folder app , trong folder services tiếp tục tạo ra 3 file, cấu trúc thư mục như sau:

Rồi, trong các file sẽ có gì?
File application_service.rb

*File activation_email_sender_service.rb *

File activate_email_service.rb

Vì sao mình lại thiết kế code như vậy?

Đầu tiên, dựa theo nguyên tắc DRY (Don’t Repeat Yourself) thì mình định nghĩa một lớp cha ApplicationService có hàm class function call truyền vào args và trong thân hàm gọi đến new(args).call sẽ tạo object và gọi hàm call trong trong class (cụ thể ở đây là 2 class con ActivateEmailServiceActivationEmailSenderService).

Thứ hai, chú ý cho việc refactor là một Service Object có 1 public method và có nhiều private method, public method ở đây của mình là function call. Ví dụ trong file activate_email_service.rb, mình có một hàm call gọi tới private function activate_email. Mọi thứ xử lý logic mình bỏ trong private function đó hết.

Thứ ba, ở đây xuất hiện một số class mới như NotFoundError, ActivatedError,… *(mình để trong cặp dấu ** trong code) * mà mình call để raise exception.
Đây là cách xử lý khi mình chuyển từ function error! trong Grape. Mình để code dưới đây để cho các bạn dễ so sánh hì.

Tương quan code trong cặp dấu ** là cách mình xử lý exception. Lúc đầu mình tưởng rằng bê qua sẽ để i chang như vậy, ai mà có dè function error! là built-in method của class Grape::API, nên mình đâu dùng được. Vậy là mình phải đi build thêm mấy cái error đó nữa.

Mình đi tạo thêm folder errors trong folder app rồi tạo các file.rb trong trỏng. Cấu trúc thư mục như sau:

Trong File application_error.rb, đây class cha cho mấy class error kia. Class này mình thừa kế từ StandardError class để từ nữa mình rescue lỗi (có 2 loại là StandardError vs Exception, mà Exception nó bắt hết nên không nên xài, tham khảo: StandardError vs Exception
File application_error.rb

File not_found_error.rb

Mấy class con kia tương tự he.

Nãy giờ là mình mới raise lỗi, giờ là lúc rescue lỗi trong API. Mình thêm dòng lệnh dưới đây vào các class API là được.

Cuối cùng, mình đi gọi các service của mình trong các API như sau:

Kết quả như sau

Trong các class hiện thực API bằng Grape

Tổng kết

Đó là một số vấn đề mình gặp phải khi refactor code. Hy vọng bài viết sẽ giúp ích được cho bạn.

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo