Đừng lặp lại chính mình hoặc DRY là một nguyên tắc quan trọng trong phát triển phần mềm. Bài đăng này sẽ chỉ cho bạn cách áp dụng nó vào cấu hình Apache APISIX. Nguyên tắc DRY "Đừng lặp lại chính mình" (DRY) là một nguyên tắc phát triển phần mềm nhằm mục đích giảm sự lặp lại của thông tin có khả năng thay đổi, thay thế thông tin bằng các khái niệm trừu tượng ít có khả năng thay đổi hơn hoặc sử dụng chuẩn hóa dữ liệu để tránh trùng lặp ngay từ đầu. -- Wikipedia - Đừng lặp lại chính mình Ý tưởng chính đằng sau DRY là nếu bạn lặp lại và thông tin thay đổi, thì bạn phải cập nhật thông tin đã thay đổi ở nhiều nơi. Không chỉ tốn thêm công sức; có khả năng bạn sẽ quên mất và có thông tin khác nhau ở nhiều nơi khác nhau. DRY tỏa sáng trong việc sửa lỗi. Hãy tưởng tượng một đoạn mã có lỗi. Hãy tưởng tượng bây giờ bạn đã sao chép đoạn mã ở hai nơi khác nhau. Bây giờ, bạn phải sửa lỗi ở hai nơi này và đó là phần dễ; phần khó là phải biết về sự trùng lặp ngay từ đầu. Có khả năng cao là người sao chép và người sửa lỗi là khác nhau. Nếu đoạn mã đã được cấu trúc lại để có thể chia sẻ và được gọi từ hai nơi thay vào đó, bạn chỉ cần sửa lỗi ở một nơi này. Hầu hết mọi người liên tưởng DRY với mã. Tuy nhiên, nó có thể hạn chế hơn và trái ngược với ý tưởng ban đầu. Nguyên tắc này đã được Andy Hunt và Dave Thomas xây dựng trong cuốn sách The Pragmatic Programmer của họ. Họ áp dụng nó khá rộng rãi để bao gồm các lược đồ cơ sở dữ liệu, kế hoạch kiểm tra, hệ thống xây dựng, thậm chí cả tài liệu. -- Wikipedia - Đừng lặp lại chính mình Hệ thống cấu hình âm thanh cho phép DRY hoặc thậm chí khuyến khích nó. DRY trong Apache APISIX Apache APISIX cung cấp cấu hình DRY ở hai nơi. Dòng chảy ngược khô Trong bối cảnh thương mại điện tử, hành trình mới bắt đầu của bạn để xác định tuyến đường trên Apache APISIX có thể bắt đầu như sau: routes: - id: 1 name: Catalog uri: /products* upstream: nodes: "catalog:8080": 1 Nếu bạn quen thuộc với APISIX, chúng tôi đã định nghĩa một tuyến đường đến danh mục theo URI . Tuy nhiên, có một vấn đề: bạn có thể muốn khách hàng tiềm năng duyệt danh mục nhưng muốn ngăn mọi người tạo, xóa hoặc cập nhật sản phẩm. Tuy nhiên, tuyến đường này khớp với mọi phương thức HTTP theo mặc định. /products Chúng ta chỉ nên cho phép người dùng đã xác thực quản lý danh mục để mọi người có thể tự do duyệt. Để triển khai phương pháp này, chúng ta cần chia tuyến đường thành hai: routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] #1 uri: /products* upstream: #2 nodes: "catalog:8080": 1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] #3 uri: /products* plugins: key-auth: ~ #4 upstream: #2 nodes: "catalog:8080": 1 Duyệt trận đấu Đã sao chép ngược dòng! Quản lý trận đấu Chỉ những người dùng đã xác thực mới có thể sử dụng tuyến đường này; là plugin đơn giản nhất cho mục đích này key-auth Chúng tôi đã khắc phục sự cố bảo mật theo cách đơn giản nhất có thể: bằng cách sao chép-dán. Bằng cách đó, chúng tôi đã sao chép phần . Nếu chúng tôi cần thay đổi cấu trúc, , bằng cách thêm hoặc xóa các nút, chúng tôi phải thực hiện ở hai nơi. Điều này phá vỡ nguyên tắc DRY. upstream ví dụ Trong các tình huống thực tế, đặc biệt là khi chúng liên quan đến container, bạn sẽ không triển khai bằng cách liệt kê . Thay vào đó, bạn nên triển khai động để thích ứng với các thay đổi về cấu trúc. Tuy nhiên, điểm vẫn đúng khi bạn cần thay đổi cấu hình hoặc triển khai khám phá dịch vụ. Do đó, quan điểm của tôi áp dụng như nhau cho các nút và khám phá dịch vụ. upstream nodes khám phá dịch vụ Cùng với trừu tượng , APISIX cung cấp trừu tượng để triển khai DRY. Chúng ta có thể viết lại đoạn mã trên như sau: Route Upstream upstreams: - id: 1 #1 name: Catalog nodes: "catalog:8080": 1 routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /products* upstream_id: 1 #2 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /products* upstream_id: 1 #2 plugins: key-auth: ~ Xác định một upstream với ID 1 Tham chiếu nó trong tuyến đường Nếu có bất cứ điều gì xảy ra trong cấu trúc, chúng ta phải cập nhật thay đổi chỉ trong duy nhất. Upstream Lưu ý rằng việc xác định nhúng và tham chiếu nó với là . upstream upstream_id loại trừ lẫn nhau Cấu hình Plugin DRY Một lĩnh vực khác mà APISIX có thể giúp bạn DRY cấu hình của mình với sự trừu tượng hóa . APISIX triển khai hầu hết các tính năng, nếu không muốn nói là tất cả, thông qua các plugin Plugin Hãy triển khai trên API của chúng ta. Chúng ta cần viết lại URL trước khi chuyển tiếp nó. phiên bản dựa trên đường dẫn routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] #1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] #1 Xóa tiền tố trước khi chuyển tiếp /v1 Giống như ở trên, phần được sao chép. Chúng ta cũng có thể đưa cấu hình plugin vào đối tượng chuyên dụng. Đoạn mã sau có cùng hiệu ứng như đoạn mã trên: upstream plugins Plugin Config plugin_configs: - id: 1 #1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 #2 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 #2 Phân tích cấu hình plugin trong một đối tượng chuyên dụng Tham khảo nó Những độc giả tinh ý có thể nhận thấy rằng tôi đã bỏ sót một phần cấu hình: đã biến mất một cách bí ẩn! Thật vậy, tôi đã xóa nó vì mục đích làm rõ. auth-key Không giống như và , và . Chúng ta có thể khắc phục sự cố chỉ bằng cách thêm bị thiếu: upstream upstream_id plugins plugin_config_id không loại trừ lẫn nhau plugin routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 plugins: key-auth: ~ #1 Sửa nó đi! Theo cách này, bạn có thể di chuyển cấu hình được chia sẻ đến đối tượng và giữ một cấu hình cụ thể ở nơi nó áp dụng. Nhưng nếu cùng một plugin với các cấu hình khác nhau được sử dụng trong và trực tiếp trong thì sao? khá rõ ràng về điều này: plugin_config plugin_config route Tài liệu > > > > Consumer Consumer Group Route Plugin Config Service Tóm lại, cấu hình trong một sẽ ghi đè lên cấu hình trong . Nó cũng cho phép chúng ta cung cấp biến cho plugin trong một và chỉ đặt nó trong một route. APISIX sẽ tìm và sử dụng khóa cho mỗi ! plugin route plugin_config_id apikey key-auth consumer consumer Phần kết luận DRY không chỉ liên quan đến mã; mà còn liên quan đến quản lý dữ liệu nói chung. Cấu hình là dữ liệu và do đó nằm trong phạm vi chung này. APISIX cung cấp hai tùy chọn DRY: một cho - và một cho - . Upstream là độc quyền; plugin cho phép ghi đè. upstream upstream_id plugin plugin_config_id Cả hai cơ chế đều giúp bạn DRY cấu hình của mình và giúp cấu hình dễ bảo trì hơn trong thời gian dài. Để đi xa hơn: Nguyên tắc Đừng lặp lại chính mình Thứ tự ưu tiên hợp nhất cấu hình Được xuất bản lần đầu tại vào ngày 1 tháng 9 năm 2024 A Java Geek