Giới thiệu
Một trong những thách thức phổ biến khi làm việc với GraphQL là quản lý sự tiến hóa của schema, đặc biệt là việc kiểm thử các thay đổi được giới thiệu trong một subgraph của API liên kết mà không làm gián đoạn lưu lượng cơ bản.
Tài liệu này trình bày một phương pháp để giải quyết thách thức đó bằng cách kết hợp WunderGraph với Signadot Sandboxes, cho phép bạn xác thực các cập nhật schema trong một môi trường tách biệt trong khi vẫn giữ được độ tin cậy của môi trường cơ bản.
Môi trường Cơ bản
Trước khi khám phá cách tích hợp Sandboxes với WunderGraph, hãy định nghĩa môi trường cơ bản.
Chúng ta sẽ tuân theo thiết lập được mô tả trong hướng dẫn Onboarding của WunderGraph Cosmo Cloud, nhưng điều chỉnh nó để chạy trên Kubernetes (sử dụng một cụm minikube cục bộ cho bản demo này).
Các yêu cầu cần có:
kubectl
vàminikube
đã được cài đặt- Tài khoản WunderGraph Cosmo
- CLI
wgc
đã được cài đặt và xác thực - Tài khoản Signadot và operator đã được cài đặt trong cụm
- CLI
signadot
đã được cài đặt và xác thực
Các bước thực hiện
Chạy các lệnh sau để chuẩn bị môi trường của bạn:
bash
# Sao chép repo signadot/examples
mkdir -p ~/git/signadot/
cd ~/git/signadot/
git clone https://github.com/signadot/examples.git
# Sao chép repo wundergraph/cosmo
mkdir -p ~/git/thrid-party/wundergraph/
cd ~/git/thrid-party/wundergraph/
git clone https://github.com/wundergraph/cosmo.git
# Xây dựng các hình ảnh demo
cd ~/git/signadot/examples/wundergraph-tutorial
eval $(minikube docker-env)
./build.sh
# Tạo đồ thị liên kết của WunderGraph và thiết lập tất cả các subgraphs
./setup-wg.sh
# Tạo token router
wgc router token create myName \
--graph-name demo \
--namespace development
# Tạo namespace và secret cho router-token
kubectl create ns wundergraph-demo
kubectl -n wundergraph-demo create secret generic router-token \
--from-literal=token=<route-token>
# Triển khai các dịch vụ cơ bản + router WunderGraph
kubectl apply -n wundergraph-demo -f ./k8s
Xác thực
Tại thời điểm này, đồ thị liên kết của bạn nên đang hoạt động và có thể nhìn thấy trong Consol của WunderGraph Cosmo. Bạn có thể mở console để xác minh rằng tất cả các subgraph đã được đăng ký và router đang khỏe mạnh.
Bạn cũng có thể khám phá GraphQL playground của router cục bộ bằng cách sử dụng Signadot:
- Bắt đầu kết nối cục bộ:
bash
signadot local connect
- Mở playground của router trong trình duyệt:
bash
http://router.wundergraph-demo.svc:3002/
- Dán truy vấn GraphQL sau vào trình chỉnh sửa:
graphql
query myEmployees {
employees {
id
products
}
}
Sử dụng Sandboxes
Để đạt được mục tiêu của chúng ta là giới thiệu các thay đổi schema mà không làm ảnh hưởng đến môi trường cơ bản, chúng ta sẽ tận dụng khả năng Feature Flags của WunderGraph.
Dưới đây là cách mà mọi thứ kết hợp lại với nhau:
- Tạo một nhánh của dịch vụ
products
sử dụng hình ảnhproducts_fg
(một phiên bản thay thế của dịch vụproducts
nơi một số cập nhật schema đã được giới thiệu).
bash
signadot sandbox apply -f - <<EOF
name: wundergraph-products
spec:
cluster: <cluster-name>
forks:
- forkOf:
kind: Deployment
namespace: wundergraph-demo
name: products
customizations:
images:
- image: signadot/wundergraph-demo-products_fg:latest
env:
- name: PORT
value: "4004"
EOF
- Sử dụng khóa định tuyến sandbox từ trên (được gọi là
<routing-key>
), tạo một subgraph tính năng của WunderGraph và một cờ tính năng tương ứng:
bash
wgc feature-subgraph create products-<routing-key> \
--namespace development \
--routing-url http://products.wundergraph-demo.svc:4004/graphql \
--subgraph products
wgc subgraph publish products-<routing-key> \
--namespace development \
--schema ./pkg/subgraphs/products_fg/subgraph/schema.graphqls
wgc feature-flag create <routing-key> \
--namespace development \
--feature-subgraphs products-<routing-key> \
--enabled
Bạn có thể tổng quát hóa quy trình trên cho nhiều dịch vụ như sau:
bash
for <service> in updatedServices; do
# Tạo một subgraph tính năng cho mỗi dịch vụ đã cập nhật
wgc feature-subgraph create <service>-<routing-key> \
--namespace development \
--routing-url <original-service-url> \
--subgraph <service>
# Xuất bản schema đã cập nhật cho dịch vụ
wgc subgraph publish <service>-<routing-key> \
--namespace development \
--schema <updated-service-schema>
done
# Cuối cùng, tạo một cờ tính năng duy nhất tham chiếu tất cả các subgraph
wgc feature-flag create <routing-key> \
--namespace development \
--feature-subgraphs <service1>-<routing-key> ... <serviceN>-<routing-key> \
--enabled
Hai bước này có thể dễ dàng được tự động hóa trong một pipeline CI: trước tiên phát hiện các dịch vụ đã thay đổi, sau đó tạo sandbox và cuối cùng cấu hình và đăng ký cờ tính năng khi mọi thứ đã sẵn sàng.
Xác thực
Nếu bạn mở lại router playground lần nữa, lần này dưới ngữ cảnh của sandbox mà bạn đã tạo (trong bản demo này chúng ta đang sử dụng tiện ích mở rộng của trình duyệt để làm như vậy), bạn sẽ nhận thấy một thuộc tính mới có sẵn trên loại employee
: trường productCount
, được phục vụ bởi nhánh products_fg
.
Nếu bạn chạy cùng một truy vấn chống lại môi trường cơ bản, bạn sẽ nhận được một lỗi vì trường productCount
không được triển khai ở đó.
Cách nó hoạt động
Các cờ tính năng của WunderGraph hoạt động thông qua tiêu đề X-Feature-Flag
.
Bởi vì khóa định tuyến của Signadot thường được truyền qua các cơ chế truyền ngữ cảnh tiêu chuẩn, chẳng hạn như W3C Trace Context và Baggage, chúng tôi cần một cách để chuyển đổi nó thành tiêu đề cờ tính năng thích hợp.
Để đạt được điều này, chúng tôi đã thêm một proxy trước Router của WunderGraph trong triển khai.
Proxy này chặn các yêu cầu, trích xuất khóa định tuyến, chuyển đổi nó thành tiêu đề X-Feature-Flag
, và sau đó chuyển tiếp yêu cầu đến Router thực tế.
Ví dụ, nếu một yêu cầu đến bao gồm tiêu đề sau:
bash
Baggage: aaa=bbb, sd-routing-key=<routing-key>, xxx=yyy
Sau khi đi qua proxy, yêu cầu sẽ trông như thế này:
bash
Baggage: aaa=bbb, sd-routing-key=<routing-key>, xxx=yyy
X-Feature-Flag: <routing-key>
Proxy đơn giản chỉ trích xuất giá trị sd-routing-key
từ tiêu đề Baggage
và thêm nó như một tiêu đề X-Feature-Flag
, để nguyên tiêu đề Baggage
ban đầu không bị thay đổi.
Do đó, luồng yêu cầu hoạt động như trong sơ đồ dưới đây:
- Một yêu cầu từ client đến proxy Envoy (trong Pod Router) trên cổng
3002
. - Proxy chuyển đổi
sd-routing-key
(tìm thấy trong tiêu đềBaggage
) thành tiêu đềX-Feature-Flag
, sau đó chuyển tiếp yêu cầu đến Router của WunderGraph (cổng13002
). - Router của WunderGraph tải schema đã được cập nhật (được kích hoạt bởi cờ tính năng).
- Để giải quyết truy vấn, nó gửi một yêu cầu đến endpoint định tuyến đã được cấu hình, mà trỏ tới URL dịch vụ gốc.
- Bởi vì yêu cầu bao gồm khóa định tuyến Signadot, DevMesh Proxy chuyển tiếp nó đến dịch vụ nhánh (
Products FG
), nơi các thay đổi schema thử nghiệm có sẵn.
Các lựa chọn thay thế
Trong một kịch bản lý tưởng, chúng ta có thể loại bỏ proxy dịch thuật trước Router.
Bởi vì Signadot hỗ trợ định tuyến sandbox sử dụng tiêu đề tùy chỉnh, nếu hệ thống nền có thể truyền tiêu đề X-Feature-Flag
trực tiếp, chúng ta có thể cấu hình nó như một tiêu đề định tuyến tùy chỉnh trong Signadot Operator. Trong trường hợp đó, tất cả logic định tuyến có thể chạy hoàn toàn dựa trên X-Feature-Flag
, loại bỏ nhu cầu về một lớp proxy bổ sung.
Một tùy chọn khác là mở rộng hoặc fork Router của WunderGraph (mà là mã nguồn mở) để thêm hỗ trợ cho các tiêu đề tùy chỉnh. Điều này sẽ cho phép Router đọc cờ tính năng trực tiếp từ tiêu đề Baggage, tránh hoàn toàn bước dịch thuật.
Kết luận
Bằng cách kết hợp cờ tính năng WunderGraph với Signadot Sandboxes, bạn có thể giới thiệu và xác thực các thay đổi schema trong một môi trường an toàn, tách biệt mà không làm gián đoạn lưu lượng cơ bản.
Cách tiếp cận này cung cấp một quy trình làm việc sạch sẽ để thử nghiệm với các trường hoặc subgraph mới, kiểm tra chúng từ đầu đến cuối và triển khai chúng với sự tự tin.
Mặc dù thiết lập hiện tại dựa vào một proxy nhẹ để dịch các khóa định tuyến thành các tiêu đề cờ tính năng, những cải tiến trong tương lai có thể đơn giản hóa kiến trúc hơn nữa.
Áp dụng mẫu này giúp các nhóm phát triển nhanh hơn trong khi duy trì độ tin cậy, biến đây thành một chiến lược thực tiễn cho việc phát triển các schema GraphQL liên kết trong các môi trường Kubernetes hiện đại.