Kiến trúc GraphQL và microservice


176

Tôi đang cố gắng hiểu nơi GraphQL phù hợp nhất để sử dụng trong kiến ​​trúc microservice.

Có một số tranh luận về việc chỉ có 1 lược đồ GraphQL hoạt động như API Gateway ủy quyền yêu cầu cho các dịch vụ siêu nhỏ được nhắm mục tiêu và ép buộc phản hồi của họ. Microservice vẫn sẽ sử dụng giao thức REST / Thrift cho suy nghĩ giao tiếp.

Thay vào đó, một cách tiếp cận khác là có nhiều lược đồ GraphQL cho mỗi microservice. Có máy chủ API Gateway nhỏ hơn định tuyến yêu cầu đến microservice được nhắm mục tiêu với tất cả thông tin của yêu cầu + truy vấn GraphQL.

Cách tiếp cận thứ 1

Có 1 Lược đồ GraphQL làm Cổng API sẽ có một nhược điểm khi mỗi lần bạn thay đổi đầu vào / đầu ra của hợp đồng microservice, chúng tôi phải thay đổi Lược đồ GraphQL tương ứng ở phía Cổng API.

Cách tiếp cận thứ 2

Nếu sử dụng Lược đồ nhiều biểu đồ cho mỗi dịch vụ siêu nhỏ, hãy hiểu theo cách nào đó vì GraphQL thực thi định nghĩa lược đồ và người tiêu dùng sẽ cần phải tôn trọng đầu vào / đầu ra được cung cấp từ microservice.

Câu hỏi

  • Liệu bạn có thấy GraphQL phù hợp để thiết kế kiến ​​trúc microservice không?

  • Làm cách nào bạn có thể thiết kế Cổng API với triển khai GraphQL có thể?

Câu trả lời:


242

Chắc chắn tiếp cận # 1.

Việc khách hàng của bạn nói chuyện với nhiều dịch vụ GraphQL (như cách tiếp cận # 2) hoàn toàn đánh bại mục đích sử dụng GraphQL ở nơi đầu tiên, đó là cung cấp một lược đồ trên toàn bộ dữ liệu ứng dụng của bạn để cho phép tìm nạp nó trong một vòng.

Có một kiến trúc không chia sẻ có vẻ hợp lý từ góc độ microservice, nhưng đối với mã phía máy khách của bạn thì đó là một cơn ác mộng tuyệt đối, bởi vì mỗi khi bạn thay đổi một trong các dịch vụ micros micros của mình, bạn phải cập nhật tất cả các máy khách của mình. Bạn chắc chắn sẽ hối tiếc điều đó.

GraphQL và microservice là một sự phù hợp hoàn hảo, bởi vì GraphQL che giấu sự thật rằng bạn có một kiến ​​trúc microservice từ các máy khách. Từ góc độ phụ trợ, bạn muốn chia mọi thứ thành microservice, nhưng từ góc độ frontend, bạn muốn tất cả dữ liệu của bạn đến từ một API duy nhất. Sử dụng GraphQL là cách tốt nhất mà tôi biết cho phép bạn làm cả hai. Nó cho phép bạn phân chia phụ trợ của bạn thành microservice, trong khi vẫn cung cấp một API duy nhất cho tất cả ứng dụng của bạn và cho phép tham gia dữ liệu từ các dịch vụ khác nhau.

Nếu bạn không muốn sử dụng REST cho các dịch vụ siêu nhỏ của mình, tất nhiên bạn có thể có mỗi người trong số họ có API GraphQL riêng, nhưng bạn vẫn nên có một cổng API. Lý do mọi người sử dụng các cổng API là để làm cho việc gọi microservice từ ứng dụng khách trở nên dễ quản lý hơn, không phải vì nó phù hợp với mẫu microservice.


2
@rcfer: Điều này thực sự có ý nghĩa :) cảm ơn. Tôi có một vài câu hỏi trên đầu câu trả lời tuyệt đẹp này. - Bạn đang nói rằng GraphQL phải được sử dụng làm cổng API? - Giả sử tôi có một Dịch vụ vi mô đặt hàng hiển thị điểm cuối REST hoặc GraphQL. Sau khi hoàn thành, tôi phải cập nhật lược đồ GraphQL chính để phản ánh chính xác cùng dữ liệu mà microservice sẽ hiển thị? Nó không âm thanh trùng lặp hoặc di chuyển ra khỏi văn hóa microservice nên được triển khai độc lập? Bất kỳ thay đổi nào đối với microservice phải được phản ánh / sao chép vào Lược đồ GraphQL chính?
Fabrizio Fenoglio

13
@Fabrizio, điều tuyệt vời với GraphQL là ngay cả khi API REST phụ trợ thay đổi, lược đồ GraphQL vẫn có thể giữ nguyên, miễn là có cách lấy dữ liệu mà dịch vụ REST đã hiển thị trước đó. Nếu nó phơi bày nhiều dữ liệu hơn, thì cách chính để xử lý vấn đề này là chỉ cần thêm các trường / loại mới vào lược đồ hiện có. Những người ở Facebook, người đã tạo ra GraphQL nói với tôi rằng họ chưa bao giờ thực hiện thay đổi đột phá đối với lược đồ của họ trong bốn năm. Tất cả các thay đổi họ thực hiện là phụ gia, có nghĩa là các khách hàng mới có thể sử dụng chức năng mới, trong khi các khách hàng cũ sẽ tiếp tục hoạt động.
Helfer

4
Đúng! :) Nhờ viết lên này! Tôi đang theo dõi bạn trên Medium và trên github thông qua repos apollo! Bài viết và bài viết của bạn rất có giá trị! :) Hãy tiếp tục phát huy! Tôi cũng nghĩ rằng một bài viết trung bình với chủ đề GraphQL + microservice sẽ rất thú vị để đọc!
Fabrizio Fenoglio

1
Cảm ơn, tôi sẽ ghi nhớ điều đó. Chắc chắn có kế hoạch viết về GraphQL và microservice tại một số điểm, nhưng có lẽ không phải trong vài tuần tới.
Helfer

Làm thế nào về sự kết hợp của tùy chọn # 2 và github.com/AEB-labs/graphql-weaver ?
Mohsen

35

Xem bài viết ở đây , trong đó cho biết làm thế nào và tại sao cách tiếp cận # 1 hoạt động tốt hơn. Cũng nhìn vào hình ảnh dưới đây được lấy từ bài báo tôi đã đề cập: nhập mô tả hình ảnh ở đây

Một trong những lợi ích chính của việc có mọi thứ đằng sau một điểm cuối duy nhất là dữ liệu có thể được định tuyến hiệu quả hơn so với mỗi yêu cầu có dịch vụ riêng. Mặc dù đây là giá trị thường được chào hàng của GraphQL, giảm độ phức tạp và dịch vụ leo thang, cấu trúc dữ liệu kết quả cũng cho phép quyền sở hữu dữ liệu được xác định cực kỳ rõ ràng và được phân định rõ ràng.

Một lợi ích khác của việc áp dụng GraphQL là về cơ bản bạn có thể khẳng định quyền kiểm soát lớn hơn đối với quá trình tải dữ liệu. Bởi vì quá trình cho các trình tải dữ liệu đi vào điểm cuối của chính nó, bạn có thể tôn trọng yêu cầu một phần, đầy đủ hoặc bằng cách cẩn thận, và do đó kiểm soát một cách cực kỳ chi tiết cách truyền dữ liệu.

Bài viết sau đây giải thích hai lợi ích này cùng với những lợi ích khác rất tốt: https://nordicapis.com/7-unique-benefits-of-USE-graphql-in-microservice/


HI, xin lỗi vì các câu hỏi của Noob, nhưng không phải cổng graphQL của bạn là điểm lưu giữ mới? Ví dụ: nếu tôi có một dịch vụ giỏ đột nhiên bị sollicited, thì cổng của tôi có bị hỏng không? Về cơ bản tôi không chắc chắn về vai trò của nó, cổng này được cho là chứa rất nhiều bộ giải quyết cho mỗi dịch vụ?
Eric Burel

1
@EricBurel Cảm ơn câu hỏi. Trên thực tế, theo như tôi hiểu từ bài viết, tất cả các lược đồ từ các dịch vụ khác nhau được thống nhất theo một lược đồ GraphQL, vì vậy như bạn đã đề cập, các dịch vụ khác vẫn nằm trên bộ dữ liệu của riêng chúng. Liên quan đến khả năng nguồn thất bại duy nhất cho cổng graphQL, luôn có các tùy chọn khác như cung cấp gói dự phòng. Vui lòng đọc bài viết này ( labs.getninjas.com.br/, ) để biết thêm thông tin. Hi vọng điêu nay co ich.
Enayat

Làm thế nào để bạn kiểm tra cổng API trung tâm và các dịch vụ riêng lẻ? Bạn đang thực hiện tích hợp hoặc chế nhạo phản hồi http?
Jaime Sangcap

7

Đối với cách tiếp cận # 2, thực tế đó là cách tôi chọn, vì nó dễ hơn nhiều so với việc duy trì cổng API gây phiền nhiễu bằng tay. Với cách này, bạn có thể phát triển dịch vụ của mình một cách độc lập. Làm cho cuộc sống dễ dàng hơn nhiều: P

Có một số công cụ tuyệt vời để kết hợp các lược đồ thành một, ví dụ như công cụ graphql-weavercông cụ graphql của apollo , tôi đang sử dụng graphql-weaver, nó rất dễ sử dụng và hoạt động rất tốt.


Sử dụng GraphQL trong Android bắt buộc tôi có thể tạo tệp .graphql với tất cả các truy vấn không? Hoặc tôi chỉ có thể tạo chúng trong mã mà không có tệp này?
MauroAlexandro

1
@MauroAlexandro Tôi không phải là một anh chàng Android, nhưng bạn có thể có các truy vấn trong các tệp khác nhau. Đó là một vấn đề thiết kế nhiều hơn. IMHO, tôi thích cái đầu tiên :)
HFX

5

Kể từ giữa năm 2019, giải pháp cho Cách tiếp cận đầu tiên bây giờ có tên là " Liên kết Schema " do người Apollo đặt ra (Trước đây, điều này thường được gọi là khâu GraphQL). Họ cũng đề xuất các mô-đun @apollo/federation@apollo/gatewaycho điều này.

THÊM: Xin lưu ý rằng với Liên kết Schema, bạn không thể sửa đổi lược đồ ở cấp độ cổng. Vì vậy, với mỗi bit bạn cần trong lược đồ của mình, bạn cần có một dịch vụ riêng.


cũng hợp lệ khi biết rằng giải pháp này yêu cầu Máy chủ Apollo bị giới hạn một chút trong phiên bản miễn phí (tối đa 25 triệu truy vấn mỗi tháng)
Marx

0

Kể từ năm 2019, cách tốt nhất là viết các kính hiển vi thực hiện thông số kỹ thuật cổng apoche và sau đó kết dính các dịch vụ này với nhau bằng cách sử dụng cổng theo cách tiếp cận # 1. Cách nhanh nhất để xây dựng cổng là hình ảnh docker như thế này Sau đó sử dụng docker-compose để bắt đầu tất cả các dịch vụ đồng thời:

version: '3'

services:
    service1:
        build: service1
    service2:
        build: service2
    gateway:
        ports:
            - 80:80
        image: xmorse/apollo-federation-gateway
        environment: 
            - CACHE_MAX_AGE=5
            - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
            - URL_0=http://service1
            - URL_1=http://service2

0

Cách nó được mô tả trong câu hỏi này, tôi tin rằng việc sử dụng cổng API tùy chỉnh làm dịch vụ điều phối có thể có ý nghĩa đối với các ứng dụng tập trung vào doanh nghiệp phức tạp. GraphQL có thể là một lựa chọn công nghệ tốt cho dịch vụ điều phối đó, ít nhất là theo như truy vấn. Lợi thế cho cách tiếp cận đầu tiên của bạn (một lược đồ cho tất cả các dịch vụ micros) là khả năng kết hợp dữ liệu từ nhiều microservice trong một yêu cầu. Điều đó có thể, hoặc có thể không, rất quan trọng tùy thuộc vào tình huống của bạn. Nếu GUI gọi để kết xuất dữ liệu từ nhiều microservice cùng một lúc, thì phương pháp này có thể đơn giản hóa mã máy khách để một cuộc gọi có thể trả về dữ liệu phù hợp với liên kết dữ liệu với các thành phần GUI của các khung như Angular hoặc React. Ưu điểm này không áp dụng cho các đột biến.

Nhược điểm là sự kết hợp chặt chẽ giữa các API dữ liệu và dịch vụ điều phối. Phát hành có thể không còn là nguyên tử. Nếu bạn không giới thiệu các thay đổi phá vỡ ngược trong API dữ liệu của mình, thì điều này chỉ có thể gây ra sự phức tạp khi quay lại một bản phát hành. Ví dụ: nếu bạn sắp phát hành phiên bản mới của hai API dữ liệu với các thay đổi tương ứng trong dịch vụ điều phối và bạn cần phải khôi phục một trong những bản phát hành đó nhưng không phải là bản phát hành khác, thì dù sao bạn cũng sẽ buộc phải quay lại cả ba.

Trong so sánh giữa GraphQL và REST, bạn sẽ thấy rằng GraphQL không hiệu quả bằng API RESTful nên tôi không khuyên bạn nên thay thế REST bằng GraphQL cho API dữ liệu.


0

Đối với câu hỏi 1, Intuit đã thừa nhận sức mạnh của GraphQL vài năm trước khi họ tuyên bố chuyển sang hệ sinh thái One Intuit API ( https://www.sl slideshoware.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integations -quickbooks-kết nối-2017 ). Intuit chọn cách tiếp cận 1. Hạn chế mà bạn đề cập thực sự ngăn cản các nhà phát triển đưa ra các thay đổi lược đồ có khả năng phá vỡ các ứng dụng khách.

GraphQL đã giúp cải thiện năng suất của các nhà phát triển theo một số cách.

  1. Khi thiết kế một microservice mới cho một miền, các kỹ sư (phụ trợ / frontend / các bên liên quan) đồng ý về một lược đồ cho các thực thể miền. Khi lược đồ được phê duyệt, nó được hợp nhất với lược đồ miền chính (phổ quát) và được triển khai trên Gateway. Các kỹ sư cuối có thể bắt đầu mã hóa các ứng dụng khách với lược đồ này trong khi các kỹ sư phụ trợ thực hiện chức năng. Có một lược đồ phổ quát có nghĩa là không có hai dịch vụ siêu nhỏ với chức năng dự phòng.
  2. GraphQL đã giúp các ứng dụng khách trở nên đơn giản và nhanh hơn. Bạn muốn lấy dữ liệu từ / cập nhật dữ liệu lên nhiều microservice? Tất cả các ứng dụng khách phải làm là thực hiện yêu cầu ONE GraphQL và lớp trừu tượng API Gateway sẽ chăm sóc để tìm nạp và đối chiếu dữ liệu từ nhiều nguồn (microservice). Các khung công tác nguồn mở như Apollo ( https://www.apollographql.com/ ) đã đẩy nhanh tốc độ áp dụng GraphQL.

  3. Với thiết bị di động là lựa chọn đầu tiên cho các ứng dụng hiện đại, điều quan trọng là phải thiết kế cho các yêu cầu băng thông dữ liệu thấp hơn từ mặt đất. GraphQL giúp bằng cách cho phép các ứng dụng khách chỉ yêu cầu các trường cụ thể.

Đối với câu hỏi 2: Chúng tôi đã xây dựng một lớp trừu tượng tùy chỉnh tại Cổng API để biết phần nào của lược đồ được sở hữu bởi dịch vụ (nhà cung cấp) nào. Khi một yêu cầu truy vấn đến, lớp trừu tượng sẽ chuyển tiếp yêu cầu đến (các) dịch vụ thích hợp. Khi dịch vụ cơ bản trả về phản hồi, lớp trừu tượng có trách nhiệm trả về các trường được yêu cầu.

Tuy nhiên, ngày nay có một số nền tảng ngoài kia (máy chủ Apollo, graphql-yoga, v.v.) cho phép một người xây dựng một lớp trừu tượng GraphQL ngay lập tức.


0

Tôi đã làm việc với GraphQL và microservice

Dựa trên kinh nghiệm của tôi, những gì hoạt động đối với tôi là sự kết hợp của cả hai cách tiếp cận tùy thuộc vào chức năng / cách sử dụng, tôi sẽ không bao giờ có một cổng duy nhất như trong cách tiếp cận 1 ... mà chỉ là một biểu đồ cho mỗi microservice như cách tiếp cận 2.

Ví dụ, dựa trên hình ảnh của câu trả lời từ Enayat, điều tôi sẽ làm trong trường hợp này là có 3 cổng biểu đồ (Không phải 5 như trong hình)

nhập mô tả hình ảnh ở đây

  • Ứng dụng (Sản phẩm, Giỏ, Vận chuyển, Hàng tồn kho, cần thiết / liên kết với các dịch vụ khác)

  • Thanh toán

  • Người sử dụng

Bằng cách này, bạn cần chú ý hơn đến việc thiết kế dữ liệu tối thiểu cần thiết / được liên kết được hiển thị từ các dịch vụ tùy thuộc, như mã thông báo xác thực, userid, Paymentid, trạng thái thanh toán

Theo kinh nghiệm của tôi, ví dụ, tôi có cổng "Người dùng", trong đó GraphQL tôi có các truy vấn / đột biến người dùng, đăng nhập, đăng nhập, đăng xuất, thay đổi mật khẩu, khôi phục email, xác nhận email, xóa tài khoản, chỉnh sửa ảnh, tải lên hình ảnh , v.v ... biểu đồ này trên chính nó khá lớn!, nó bị tách ra vì cuối cùng, các dịch vụ / cổng khác chỉ quan tâm đến thông tin kết quả như userid, name hoặc token.

Cách này dễ hơn để ...

  • Chia tỷ lệ / tắt các nút cổng khác nhau tùy thuộc vào cách sử dụng. (ví dụ, mọi người có thể không phải lúc nào cũng chỉnh sửa hồ sơ hoặc trả tiền ... nhưng việc tìm kiếm sản phẩm có thể được sử dụng thường xuyên hơn).

  • Khi một cổng trưởng thành, phát triển, việc sử dụng được biết đến hoặc bạn có nhiều kiến ​​thức chuyên môn về miền mà bạn có thể xác định đó là một phần của lược đồ có thể sở hữu cổng đó (... đã xảy ra với tôi với một lược đồ lớn tương tác với kho git , Tôi đã tách cổng tương tác với kho lưu trữ và tôi thấy rằng thông tin cần thiết / liên kết đầu vào duy nhất là ... đường dẫn thư mục và nhánh dự kiến)

  • Lịch sử của kho lưu trữ của bạn rõ ràng hơn và bạn có thể có một kho lưu trữ / nhà phát triển / nhóm dành riêng cho một cổng và các dịch vụ siêu nhỏ liên quan của nó.

CẬP NHẬT:

Tôi có một cụm kubernetes trực tuyến đang sử dụng cùng một cách tiếp cận mà tôi mô tả ở đây với tất cả các phụ trợ sử dụng GraphQL, tất cả mã nguồn mở, đây là kho lưu trữ chính: https://github.com/vicjicaman/microservice-realm

Đây là bản cập nhật cho câu trả lời của tôi vì tôi nghĩ rằng sẽ tốt hơn nếu câu trả lời / cách tiếp cận được sao lưu mã đang chạy và có thể được tư vấn / xem xét, tôi hy vọng rằng điều này sẽ giúp ích.


-3

Vì kiến ​​trúc microservice không có định nghĩa đúng, không có mô hình cụ thể cho kiểu này, nhưng, hầu hết chúng sẽ có một vài đặc điểm đáng chú ý. Trong trường hợp kiến ​​trúc microservice, mỗi dịch vụ có thể được chia thành các thành phần nhỏ riêng lẻ, có thể được chia thành các thành phần nhỏ riêng lẻ. cá nhân tinh chỉnh và triển khai mà không ảnh hưởng đến tính toàn vẹn của ứng dụng. Điều này có nghĩa là bạn chỉ có thể thay đổi một vài dịch vụ mà không cần triển khai lại ứng dụng thông qua phát triển ứng dụng microservice tùy chỉnh .


Ngay cả khi thiếu một "định nghĩa đúng", đó là một khái niệm được hiểu rõ và phân định rõ ràng trong bối cảnh của câu hỏi. Điều đó sang một bên, câu trả lời của bạn không giải quyết câu hỏi nào cả.
Roy Prins

-7

Nói thêm về microservice, tôi nghĩ rằng GraphQL cũng có thể hoạt động hoàn hảo trong kiến ​​trúc không có máy chủ. Tôi không sử dụng GraphQL nhưng tôi có dự án tương tự của riêng mình . Tôi sử dụng nó như một công cụ tổng hợp để gọi và tập trung nhiều chức năng vào một kết quả duy nhất. Tôi nghĩ bạn có thể áp dụng mô hình tương tự cho GraphQL.


2
Xin lỗi, nhưng điều này không liên quan đến câu hỏi của OP. Câu hỏi là về hai cách tiếp cận cụ thể bằng cách sử dụng GraphQL. Điều này có thể đã được đưa vào tốt hơn như là một bình luận.
tiomno
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.