Input data: Working on client-server application on IOS (Swift 5.2) with GraphQL and using Apollo for networking. Without going into the details of the GraphQL and Apollo work, we have:
public protocol GraphQLOperation: class {
associatedtype Data: GraphQLSelectionSet
...
}
public protocol GraphQLQuery: GraphQLOperation {}
public protocol GraphQLMutation: GraphQLOperation {}
these protocols for GraphQL operations in Apollo, GraphQLMutation for mutations, and GraphQLQuery for queries respectively. They are inherited from main GraphQLOperation with associated type which is used for return type. Mutations
and Queries
are generated by Apollo with code generation into final classes inherited from GraphQLQuery
or GraphQLMutation
with generated Data structure inherited from the GraphQLSelectionSet
inside of the class. Simplified version of generated class looks like:
public final class RegisterUserMutation: GraphQLMutation {
...
public struct Data: GraphQLSelectionSet { ... generated data ... }
...
}
For executing requests Apollo has two methods:
func perform<Mutation: GraphQLMutation>(mutation: Mutation...)
func fetch<Query: GraphQLQuery>(query: Query...)
What I need? Need own NetworkClient with ApolloClient under the hood.
Wherefore: errors handling and mapping GraphQL errors to custom errors, user token prolongation logic for all requests -> all in one place. Incapsulate network logic behind the protocol.
Accordingly, i want to have one entry point in the network client for all requests and manage it already inside.
Solution: I am trying to write Network Client with one entry point for all requests:
protocol NetworkClient {
func execute<Command: NetworkCommand>(command: Command) -> Response<Command.Data>
}
Where Command looks like:
protocol NetworkCommand {
associatedtype Operation: GraphQLOperation
typealias Data = Operation.Data
var operationType: GraphQLOperationType { get }
func getOperation() -> Operation
}
protocol MutationCommand: NetworkCommand where Operation: GraphQLMutation {}
protocol QueryCommand: NetworkCommand where Operation: GraphQLQuery {}
class RegisterUserCommand: MutationCommand {
typealias Operation = RegisterUserMutation
var operationType: GraphQLOperationType = .mutation
func getOperation() -> RegisterUserMutation {
return RegisterUserMutation(birthDate: "", email: "", password: "", sex: .female, username: "")
}
}
And the implementation looks like:
class NetworkClientImpl: NetworkClient {
private let apolloClient: ApolloClient
init(client: ApolloClient) {
self.apolloClient = client
}
func execute<Command>(command: Command) -> Response<Command.Data> where Command : NetworkCommand {
switch command.operationType {
case .mutation:
let mutation = command.getOperation()
apolloClient.perform(mutation: mutation as! GraphQLMutation)
default:
<#code#>
}
}
}
**Problem: ** I am getting the error in combining Apollo request types:
Is it possible to combine them?
Aucun commentaire:
Enregistrer un commentaire