将 Apollo iOS Client GraphQL 查询变量和 url 记录到控制台?
Posted
技术标签:
【中文标题】将 Apollo iOS Client GraphQL 查询变量和 url 记录到控制台?【英文标题】:Log Apollo iOS Client GraphQL query variables and url to console? 【发布时间】:2021-04-24 02:57:10 【问题描述】:我想在调用查询时将我的 Apollo ios 客户端 GraphQL 查询的 url 打印到 Xcode 控制台。
【问题讨论】:
【参考方案1】:您无需编写 swift 代码即可提取 QueryName。
使用 Proxyman,例如 Charles Proxy。默认情况下,它将在列上显示 QueryName。
参考:https://docs.proxyman.io/advanced-features/graphql
【讨论】:
【参考方案2】:根据Apollo iOS Client docs,可以在自定义拦截器提供程序中添加日志拦截器。
我使用来自 DefaultInterceptorProvider 的代码创建了一个自定义拦截器提供程序,并包含了日志拦截器。
import Apollo
class InterceptorProviderWithLogging: InterceptorProvider
private let client: URLSessionClient
private let store: ApolloStore
private let shouldInvalidateClientOnDeinit: Bool
public init(client: URLSessionClient = URLSessionClient(),
shouldInvalidateClientOnDeinit: Bool = true,
store: ApolloStore)
self.client = client
self.shouldInvalidateClientOnDeinit = shouldInvalidateClientOnDeinit
self.store = store
deinit
if self.shouldInvalidateClientOnDeinit
self.client.invalidate()
open func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor]
return [
MaxRetryInterceptor(),
CacheReadInterceptor(store: self.store),
RequestLoggingInterceptor(), // added logging interceptor
NetworkFetchInterceptor(client: self.client),
ResponseCodeInterceptor(),
JSONResponseParsingInterceptor(cacheKeyForObject: self.store.cacheKeyForObject),
AutomaticPersistedQueryInterceptor(),
CacheWriteInterceptor(store: self.store),
]
open func additionalErrorInterceptor<Operation: GraphQLOperation>(for operation: Operation) -> ApolloErrorInterceptor?
return nil
class RequestLoggingInterceptor: ApolloInterceptor
func interceptAsync<Operation: GraphQLOperation>(
chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void)
if let url = try? request.toURLRequest().url?.absoluteString.removingPercentEncoding
if let variables = request.operation.variables
print("\(request.operation.operationName) parameters: \(variables) \(url)")
else
print("\(request.operation.operationName) \(url)")
chain.proceedAsync(request: request, response: response, completion: completion)
我在请求链网络传输中使用自定义拦截器提供程序。
private(set) lazy var apolloClient: ApolloClient =
let store = ApolloStore()
let interceptorProvider = InterceptorProviderWithLogging(store: store)
let requestChainTransport = RequestChainNetworkTransport(
interceptorProvider: interceptorProvider,
endpointURL: url,
additionalHeaders: [:],
autoPersistQueries: false,
requestBodyCreator: ApolloRequestBodyCreator(),
useGETForQueries: true,
useGETForPersistedQueryRetry: false
)
return ApolloClient(networkTransport: requestChainTransport, store: store)
()
【讨论】:
【参考方案3】:扩展 GraphQLQuery 提供对操作名称、操作 ID 和变量的访问,这些可用于构建 url。我还打印出查询的操作名称和变量。
extension GraphQLQuery
func printInfo()
if let variables = self.variables?.JSONString
let cleanedVariables = variables.replacingOccurrences(of: "\\", with: "")
print("GraphQL Query: \(self.operationName) \(variables))")
if let operationID = self.operationIdentifier
let url = "\(GraphQLClient.shared.url)?extensions=\"persistedQuery\":\"sha256Hash\":\"\(operationID)\",\"version\":1&id=\(operationID)&operationName=\(self.operationName)&variables=\(cleanedVariables)"
print("GraphQL URL", url)
else
print("GraphQL Query: \(self.operationName)")
if let operationID = self.operationIdentifier
let url = "\(GraphQLClient.shared.url)?extensions=\"persistedQuery\":\"sha256Hash\":\"\(operationID)\",\"version\":1&id=\(operationID)&operationName=\(self.operationName)"
print("GraphQL URL", url)
用法:
let standingsQuery = GetStandingsForSportQuery(sportID: sportIDInt, season: season)
standingsQuery.printInfo()
示例输出:
GraphQL Query: getStandingsForSport "sportID":7,"season":"2020")
GraphQL URL: https://api.company.com/graphql?extensions="persistedQuery":"sha256Hash":"932b414fdadb641f95659d6c61aa29d6d6b0ccf1fa704a0ace751187b90b8cac","version":1&id=932b414fdadb641f95659d6c61aa29d6d6b0ccf1fa704a0ace751187b90b8cac&operationName=getStandingsForSport&variables="sportID":1,"season":"2020"
此示例中的 url 格式可能不是典型的,因为我们使用的是持久化查询。我使用 Charles 代理查看发送的实际 url,所以我知道格式。
您还可以扩展 GraphQLOperation 而不是 GraphQLQuery 来获取相同的信息,这也将支持突变和订阅。
【讨论】:
有一个简单的方法来获取QueryName:docs.proxyman.io/advanced-features/…以上是关于将 Apollo iOS Client GraphQL 查询变量和 url 记录到控制台?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Apollo Client for iOS 读取结果
在 GraphQL Apollo Client iOS 中模拟 JSON 数据解析
如何将 localStorage 与 apollo-client 和 reactjs 一起使用?