/
Service Contract/WebApi (1.5d)

Service Contract/WebApi (1.5d)

https://devdocs.magento.com/guides/v2.4/extension-dev-guide/service-contracts/service-contracts.html

https://devdocs.magento.com/guides/v2.4/extension-dev-guide/api-concepts.html

https://docs.google.com/presentation/d/1L49RN2RXH55lBEpjsD2v5JWa1fALOmuP/edit?usp=share_link&ouid=112566144493030284998&rtpof=true&sd=true

Lý thuyết

Hợp đồng dịch vụ (Service Contracts)

Magento là một hệ thống cho phép các nhà lập trình bên thứ ba có thể tùy chỉnh và ghi đè lên phần core của nó. Sự linh hoạt này khiến cho magento dễ tùy biến hơn, tuy nhiên, đi kèm theo nó là một số vấn đề gặp phải.

-Logic xử lí có xu hướng bị rò rỉ trên các class của Magento, mà biểu hiện như sự trùng lặp và không nhất quán trong code.

-Người chủ website có thể lưỡng lự khi nâng cấp Magento vì các extension mà họ đã mua có thể không tương thích với các phiên bản mới của Magento. Ngoài ra, Magento và nhà phát triển bên thứ ba có thể gặp khó khăn để theo dõi sự phụ thuộc vào những extension khác với nhau.

Để giải quyết những vấn đề này, Magento đã đề ra "Hợp đồng dịch vụ" (Service Contracts).

Một hợp đồng dịch vụ (Service Contract) là gì?

"Hợp đồng dịch vụ" là một bộ PHP Interface được định nghĩa cho một module. Hợp đồng dịch vụ bao gồm các data interfaces dùng để bảo tồn tính toàn vẹn dữ liệu và service interfaces để cung cấp các xử lí. Chi tiết logic xử lí được ẩn đi với các phần sử dụng dịch vụ (như controller, web services và các module khác).

Nếu developer định nghĩa data và service interfaces theo một mẫu thiết kế, API của các modules khác và các extension bên thứ ba có thể implement nó thông qua Magento models và resource models.

Dưới đây là hình ảnh mô tả về cấu trúc của Magento 2 tuân theo Service Contract:

 

Trong hình ảnh trên, các bạn có thể thấy Controllers, Web Services, Other modules không thao tác trực tiếp với thành phần Model và Resource Model mà giao tiếp thông qua interface. Logic xử lí được ẩn đi, các thành phần sử dụng service chỉ quan tâm đến đầu ra và đầu vào chứ không cần quan tâm đến logic xử lí.

Ví dụ Interface: Magento\Catalog\Api\ProductRepositoryInterface

public function delete(\Magento\Catalog\Api\Data\ProductInterface $product);

Ví dụ Model implements Interface: Magento\Catalog\Model\ProductRepository

public function delete(\Magento\Catalog\Api\Data\ProductInterface $product) { $sku = $product->getSku(); $productId = $product->getId(); try { unset($this->instances[$product->getSku()]); unset($this->instancesById[$product->getId()]); $this->resourceModel->delete($product); } catch (ValidatorException $e) { throw new CouldNotSaveException(__($e->getMessage())); } catch (\Exception $e) { throw new \Magento\Framework\Exception\StateException( __('Unable to remove product %1', $sku) ); } unset($this->instances[$sku]); unset($this->instancesById[$productId]); return true; }

Việc model nào ứng với interface nào được cấu hình trong file etc/di.xml của magento 2.

<preference for="Magento\Catalog\Api\ProductRepositoryInterface" type="Magento\Catalog\Model\ProductRepository" />

Lợi ích của hợp đồng dịch vụ (Service Contracts)

Để giải thích dễ hiểu hơn về lợi ích của Service Contract, mình sẽ đưa ra ví dụ sau:

Giả sử có 2 công ty A và B. Công ty A yêu cầu công ty B làm cho mình một chiếc xe ô tô. Công ty A sẽ kí với công ty B một bản hợp đồng cam kết là sẽ ô tô phải có đủ tính năng và đặc điểm như: màu vàng, chạy êm, 20 chỗ ngồi, … . Công ty B sẽ giao dự án này cho team Eden thực hiện.

ở đây ta có thể hiểu: - Công ty A ứng với Module A - Công ty B ứng với Module B - Hợp đồng ứng với Interface (data interface và service interface) - Team Eden ứng với Model và Resource Model của Magento

Như chúng ta thấy, Công ty A sẽ không giao tiếp trực tiếp với team Eden mà thông qua công ty và đại diện cho nó là bản hợp đồng đã được ký kết. Việc ai thực hiện dự án này sẽ do nội bộ công ty B quyết định, và công ty A sẽ không can thiệp và cũng không biết tới nó. Giả dụ, nếu team Eden không thực hiện dự án, thì công ty B sẽ giao cho một team khác (team Eagle). Sự thay đổi này chỉ diễn ra trong nội bộ công ty B và công ty A không phải chịu ảnh hương gì cả.

Ưng với Magento và service contract, ta có thể thấy, sự thay đổi về Model và Resource Model trong Module B sẽ không gây ảnh hưởng đến Module A. Giả dụ có sự thay đổi, Module B chỉ cần đổi trong file di.xml để thay thế thôi và không gây ảnh hưởng tới các thành phần sử dụng service.

Service Contracts tăng cường khả năng module hóa của Magento. Chúng cho phép Magento và các nhà phát triển bên thứ ba có thể theo dõi sự phụ thuộc hệ thống thông qua những file composer.json và, do đó, đảm bảo tương thích giữa các phiên bản Magento. Điều này đảm bảo rằng người dùng Magento có thể dễ dàng nâng cấp lên các phiên bản Magento mới nhất.

Các service interface này được xác định rõ để các API của module khác và extension bên thứ ba có thể implement nó được.

Các loại Interface và nơi định nghĩa

Có hai loại interface trong mô hình service contracts, đó là Data Interfaces và Service Interfaces.

Data interfaces

Data interfaces được dùng để bảo tồn tính toàn vẹn dữ liệu. Data interfaces định nghĩa các hàm mà trả lại thông tin về các thực thể dữ liệu (data entities), kết quả tìm kiếm, và xác thực kết quả. Bạn phải định nghĩa các data interface cho một service contract trong thư mục Api/Data.

Ví dụ, data interfaces cho module Customer nằm trong thư mục /app/code/Magento/Customer/Api/Data.

Ví dụ về trả về kết quả tìm kiếm (data search results interfaces):

Khi bạn truyền các tiêu chí tìm kiếm và gọi hàm getList (), một search results interface được trả về với kết quả tìm kiếm. Trong một search results interface thường chứa hàm getItems trả về một mảng các data entites (thực thể dữ liệu). Ví dụ, Hàm getItems () trong CustomerSearchResultsInterface trả về một mảng của các thực thể dữ liệu CustomerInterface. GroupSearchResultsInterface, hàm getItems () trả về một mảng các thực thể dữ liệu GroupInterface.

Service interfaces

Service interfaces được dùng để ẩn logic xử lí từ các bên yêu cầu dịch vụ (service requestors). Bạn phải định nghĩa các service interfaces cho một service contract trong thư mục con Api của một module. Service interface bao gồm:

  • Repository interfaces

  • Management interfaces

  • Metadata interfaces

Cách đặt tên cần tuân theo chuẩn code của Magento. Mình sẽ mô tả cụ thể về các loại service interface ngay sau đây.

– Repository interfaces

Repository Interfaces cung cấp quyền truy cập vào một thực thể dữ liệu (Data entity). Chúng ta thường dùng Repository Interfaces trong trường hợp cần cung cấp các thao tác thêm, sửa, xóa, lấy dữ liệu.

Ví dụ, các thực thể dữ liệu (data entities) cho module Customer bao gồm Customer, Address, và Group. Do đó, các Repository Interfaces cho module Customer là: CustomerRepositoryInterface, AddressRepositoryInterface, GroupRepositoryInterface

Một Repository Interfaces phải cung cấp các chức năng:

  • save (data entity interface): Nếu ID chưa có, tạo một bản ghi mới. Nếu có rồi, cập nhật dữ liệu cho bản ghi đó

  • get(id): tìm kiếm trong database theo ID. Sẽ trả về một data entity interface. Ví dụ như CustomerInterface

  • getList(search criteria): Tìm kiếm tất cả các data entites phù hợp với yêu cầu tìm kiếm. Sẽ trả về một search results interface

  • delete(data entity interface): Xóa một entity cụ thể. Entity này phải chứa ID.

  • deleteById(id): Xóa một entity theo ID

Sau đây là một ví dụ về CustomerRepositoryInterface:

– Management interfaces

Management interfaces cung cấp chức năng quản lý mà không liên quan đến các Repository Interfaces. Ví dụ:

  • AccountManagementInterface: cung cấp chức năng như tạo tài khoản createAccount(), đổi password changePassword() ...

  • AddressManagementInterface: cung cấp chức năng validate() để xác thực một address.

  • Metadata interfaces

Metadata interface cung cấp thông tin về những gì thuộc tính (attributes) được định nghĩa cho một thực thể. Metadata interface thường dùng để định nghĩa thêm các custom attributes cho một entity cho Magento. Ví dụ như customer entity cần thêm các custom attribute, do đó sẽ có CustomerMetadataInterface:

Sau đây là ví dụ về CustomerMetadataInterface:

Như vậy mình đã trình bày xong về mô hình Service Contracts trong Magento 2. Đây là một mẫu design pattern khá quan trọng trong Magento 2 mà mọi developer Magento 2 đều cần phải biết. Hiện tại, mô hình này đang được áp dụng rất phổ biến trong các module của Magento 2. Các bạn có thể tự xem thêm trong code core của Magento 2, cụ thể là 2 module Customer và Checkout để biết sâu thêm về các loại Data Interfaces và Service Interfaces trong mô hình này.

API:

Tạo file etc/webapi.xml

url: tên đường dẫn khi gọi api

method: POST, PUT, GET, DELETE: phương thức gửi data lên api

service class: trỏ tới interface thực hiện api

service method: hàm xử lí của api

resource: dùng để xác thực, anonymous là bỏ qua xác thực

Ví dụ:

Call api:

Gọi đường dẫn:

http://[domain]/rest/default/V1/webpos/website/information với method là GET

để thực thi API

Bài tập:

  • Create database to store student data, design the table structure by yourself

  • Use service contract, write repository with the function getList, delete, deleteById,, getById, save

  • Create REST API to CRUD (Create, read , update, delete) student with resource anonymous.

Related content

Magento 2 Document
Magento 2 Document
Read with this
Simple POS (Client)
Simple POS (Client)
More like this
Another Technique (2d)
Another Technique (2d)
Read with this
Model/Resource Model/Collection (1 day)
Model/Resource Model/Collection (1 day)
Read with this
Simple POS (Magento Backend + API)
Simple POS (Magento Backend + API)
Read with this
Exercise Component Section
Exercise Component Section
Read with this