跳至主要内容

GraphQL 搞微服務必備良器: GraphQL Gateway

API Gateway

微服務的其中一個目的就是拆分服務職責,把一個巨大的服務切分成許多微服務,讓各服務都有專門負責的項目,以一個社群網站來說,可能會有以下分工:

  • 貼文服務: 負責與貼文相關的功能,例如編輯器、貼文渲染等
  • 留言服務: 負責與留言相關的功能,例如留言區塊、留言按讚、留言回覆等
  • 交友圈服務: 負責交友功能,例如加好友、管理好友等

以一個成熟服務來說,不太可能將以上這些功能整合在一個服務內,不僅有職責拆分上的管理麻煩、還可能導致高度耦合,因此希望透過微服務的拆分達到各司其職。但當服務都拆分開來後,我們需要管理各服務端點,像是 api/post 導向 Post Serverapi/comment 導向 Comment Server等,RESTful API 的設計方式可以輕易讓 Ngnix 這類代理去做到,e.x.

location /api/ {
location /api/post {
proxy_pass https://post_service;
}

location /api/comment {
proxy_pass https://comment_service;
}

return 404; # Catch-all
}

而這種方式就是 API Gateway,但是跟到這邊的讀者會發現 GraphQL 的端點都是 /graphql,當然我們可以透過不同服務更換端點去做到 API Gateway,在 NestJS 中更改 path,e.x.

    GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: 'schema.gql',
playground: true,
// subscriptions: {
// 'graphql-ws': true,
// },
installSubscriptionHandlers: true,
path: '/post',
}),

但是 GraphQL 最重要的是 Schema 的型態管制,在不同服務間需要外部關聯的時候能發揮 Schema 類型參照的功用,而透過 Ngnix 做的 API Gateway 是不會讓各服務間知道各自的 Schema 的,慶幸地,GraphQL 給予了一個很好的解法: GraphQL Gateway

GraphQL Gateway

在開始實作前,我們需要先了解在 GraphQL 是怎麼透過 GraphQL Gateway 讓微服務溝通的。每個微服務會依照自己的職責開發出 GraphQL 的服務,同時創造出該服務的 Graph,在 GraphQL Gateway 的架構底下稱之為 subgraph,而在這些微服務的上層會有個主要的服務,也就是 Gateway 本身,會將 subgraphs 集結成 supergraph,而這些 subgraph 則須遵守 GraphQL service 的架構,以 Apollo 來說,掌管 subgraph 的架構即為 Apollo Federation

supergraph & subgraph

References: