使用 API 密钥查询 GraphQL 微服务?

问题描述

在这两个微服务之上开发了两个 Netflix DGS GraphQL 微服务和 Apollo Gateway,使它们成为一个联合的 graphql。 我有一个客户端应用程序试图查询这两个 graphql 微服务。并且这两个微服务都有一个唯一的 API 密钥。我们如何为来自客户端或 Apollo 服务器的多个微服务分配 API 密钥? 当客户端使用 API 密钥查询多个微服务时,服务器可能会忽略 API 密钥。是否有处理 API 密钥管理的最佳做法?

解决方法

Apollo Gateway 具有 buildService 属性,您可以使用该属性使用 willSendRequest 等标准回调修改请求行为。

使用 willSendRequest,您可以匹配服务 URL 并相应地附加 API 密钥:

class RequestHander extends RemoteGraphQLDataSource {
    willSendRequest({ request }: { request: GraphQLRequest }) {
        // if request.http.url matches url of a service which you
        // use,add api-key to headers,e.g.
        if (request.http.url === 'http://localhost:3001') {
            request.http.headers.set('api-key',<API_KEY>)
        }
    }
}

const main = () => {
    const gateway = new ApolloGateway({
        buildService: ({ url }) => new RequestHander({ url }),serviceList: [
            { name: 'service1',url: 'http://localhost:3001' },{ name: 'service2',url: 'http://localhost:3002' },],})

    const server = new ApolloServer({ gateway })

    void server.listen({ port: 3000 }).then(({ url }) => {
        logger.info(`Apollo Gateway ready at ${url}`)
    })
}

main()

通过这种方式,您可以创建一些地图,其中您将列出所有服务并列出其 api 键,然后您将能够以简单的方式匹配 willSendRequest 回调中的 url 和 api 键。>