Nguon: Microsoft Learn · .NET 8.0

YARP Configuration Filters (Bộ lọc cấu hình YARP)

Nguồn: YARP Configuration Filters

Giới thiệu

Cấu hình YARP cho routes, clusters và destinations có thể được tải từ configuration files (tệp cấu hình) hoặc từ configuration providers (nhà cung cấp cấu hình). Configuration filters (bộ lọc cấu hình) có thể được sử dụng để sửa đổi dữ liệu đầu vào thô trước khi nó được xác thực và áp dụng.

Filters có thể được sử dụng cho nhiều mục đích khác nhau như:

AddConfigFilter

Configuration filters được đăng ký trong hệ thống Dependency Injection (DI) bằng API AddConfigFilter. Có thể thêm bất kỳ số lượng filter duy nhất nào và chúng sẽ được áp dụng theo thứ tự thêm vào.

csharp
// Tải cấu hình và đăng ký config filter
services.AddReverseProxy()
    .LoadFromConfig(_configuration.GetSection("ReverseProxy"))
    .AddConfigFilter<CustomConfigFilter>();

IProxyConfigFilter

Configuration filters được viết bằng interface IProxyConfigFilter. Vì filters được đăng ký trong DI, chúng có thể định nghĩa constructor để inject (tiêm) bất kỳ dependency (phụ thuộc) nào.

Filters được gọi cho mỗi route và cluster mỗi khi cấu hình được tải hoặc tải lại. Chúng có thể chọn trả về dữ liệu đầu vào gốc không thay đổi hoặc một bản sao đã được sửa đổi. Cú pháp records của C# 9 rất tiện dụng để tạo các bản sao đã sửa đổi.

Ví dụ này điền địa chỉ destination từ biến môi trường và đặt trường Order của route là 1.

csharp
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Yarp.ReverseProxy.Configuration;

namespace Yarp.Sample;

public class CustomConfigFilter : IProxyConfigFilter
{
    // Khớp với {{env_var_name}}
    private readonly Regex _exp = new("\\{\\{(\\w+)\\}\\}");

    // Mẫu này xem xét địa chỉ destination và bất kỳ địa chỉ nào có dạng {{key}} sẽ được sửa đổi,
    // tra cứu key như một biến môi trường. Điều này hữu ích khi được host trên Azure, v.v.,
    // vì nó cho phép một cách đơn giản để thay thế địa chỉ destination qua management console
    public ValueTask<ClusterConfig> ConfigureClusterAsync(ClusterConfig origCluster, CancellationToken cancel)
    {
        // Mỗi cluster có một dictionary của destinations, đây là read-only,
        // vì vậy chúng ta sẽ tạo một cái mới với các cập nhật của mình
        var newDests = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase);

        foreach (var d in origCluster.Destinations)
        {
            var origAddress = d.Value.Address;
            if (_exp.IsMatch(origAddress))
            {
                // Lấy tên của biến môi trường từ destination và tra cứu giá trị
                var lookup = _exp.Matches(origAddress)[0].Groups[1].Value;
                var newAddress = Environment.GetEnvironmentVariable(lookup);

                if (string.IsNullOrWhiteSpace(newAddress))
                {
                    throw new ArgumentException($"Configuration Filter Error: Substitution for '{lookup}' in cluster '{d.Key}' not found as an environment variable.");
                }

                // Sử dụng cú pháp "with" của C# 9 để clone và khởi tạo một record mới
                var modifiedDest = d.Value with { Address = newAddress };
                newDests.Add(d.Key, modifiedDest);
            }
            else
            {
                newDests.Add(d.Key, d.Value);
            }
        }

        return new ValueTask<ClusterConfig>(origCluster with { Destinations = newDests });
    }

    public ValueTask<RouteConfig> ConfigureRouteAsync(RouteConfig route, ClusterConfig cluster, CancellationToken cancel)
    {
        // Ví dụ: không để các route dựa trên cấu hình có độ ưu tiên cao hơn các route dựa trên code.
        // Số nhỏ hơn có độ ưu tiên cao hơn. Các code route mặc định là 0.
        if (route.Order.HasValue && route.Order.Value < 1)
        {
            return new ValueTask<RouteConfig>(route with { Order = 1 });
        }

        return new ValueTask<RouteConfig>(route);
    }
}