Skip to content

Commit 8479bb9

Browse files
feature: Makes connection_init payload type generic
This allows the user to define their own authorization types, but still allows us to encode/decode in a strongly typed way. Some common default payload types are included.
1 parent 16eaa0b commit 8479bb9

File tree

5 files changed

+29
-30
lines changed

5 files changed

+29
-30
lines changed

Sources/GraphQLTransportWS/Client.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Foundation
44
import GraphQL
55

66
/// Client is an open-ended implementation of the client side of the protocol. It parses and adds callbacks for each type of server respose.
7-
public class Client {
7+
public class Client<InitPayload: Equatable & Codable> {
88
// We keep this weak because we strongly inject this object into the messenger callback
99
weak var messenger: Messenger?
1010

@@ -110,7 +110,7 @@ public class Client {
110110
}
111111

112112
/// Send a `connection_init` request through the messenger
113-
public func sendConnectionInit(payload: ConnectionInitAuth?) {
113+
public func sendConnectionInit(payload: InitPayload) {
114114
guard let messenger = messenger else { return }
115115
messenger.send(
116116
ConnectionInitRequest(
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Contains convenient `connection_init` payloads for users of this package
2+
3+
/// `connection_init` `payload` that is empty
4+
public struct EmptyInitPayload: Equatable & Codable { }
5+
6+
/// `connection_init` `payload` that includes an `authToken` field
7+
public struct TokenInitPayload: Equatable & Codable {
8+
let authToken: String
9+
}

Sources/GraphQLTransportWS/Requests.swift

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,14 @@ import GraphQL
1515
/// ```
1616

1717
/// A general request. This object's type is used to triage to other, more specific request objects.
18-
public struct Request: Equatable, JsonEncodable {
18+
struct Request: Equatable, JsonEncodable {
1919
let type: RequestMessageType
2020
}
2121

2222
/// A websocket `connection_init` request from the client to the server
23-
public struct ConnectionInitRequest: Equatable, JsonEncodable {
23+
struct ConnectionInitRequest<InitPayload: Codable & Equatable>: Equatable, JsonEncodable {
2424
var type = RequestMessageType.connectionInit
25-
public let payload: ConnectionInitAuth?
26-
}
27-
28-
// TODO: Make this structure user-defined
29-
/// Authorization format for a websocket `connection_init` request from the client to the server
30-
public struct ConnectionInitAuth: Equatable, JsonEncodable {
31-
public let authToken: String
32-
33-
public init(authToken: String) {
34-
self.authToken = authToken
35-
}
25+
let payload: InitPayload
3626
}
3727

3828
/// A websocket `subscribe` request from the client to the server

Sources/GraphQLTransportWS/Server.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import NIO
77
import RxSwift
88

99
/// Server implements the server-side portion of the protocol, allowing a few callbacks for customization.
10-
public class Server {
10+
public class Server<InitPayload: Equatable & Codable> {
1111
// We keep this weak because we strongly inject this object into the messenger callback
1212
weak var messenger: Messenger?
1313

1414
let onExecute: (GraphQLRequest) -> EventLoopFuture<GraphQLResult>
1515
let onSubscribe: (GraphQLRequest) -> EventLoopFuture<SubscriptionResult>
1616

17-
var auth: (ConnectionInitRequest) throws -> Void = { _ in }
17+
var auth: (InitPayload) throws -> Void = { _ in }
1818
var onExit: () -> Void = { }
1919
var onMessage: (String) -> Void = { _ in }
2020

@@ -64,7 +64,7 @@ public class Server {
6464

6565
switch request.type {
6666
case .connectionInit:
67-
guard let connectionInitRequest = try? self.decoder.decode(ConnectionInitRequest.self, from: data) else {
67+
guard let connectionInitRequest = try? self.decoder.decode(ConnectionInitRequest<InitPayload>.self, from: data) else {
6868
self.error(.invalidRequestFormat(messageType: .connectionInit))
6969
return
7070
}
@@ -89,7 +89,7 @@ public class Server {
8989

9090
/// Define the callback run during `connection_init` resolution that allows authorization using the `payload`.
9191
/// Throw to indicate that authorization has failed. /// - Parameter callback: The callback to assign
92-
public func auth(_ callback: @escaping (ConnectionInitRequest) throws -> Void) {
92+
public func auth(_ callback: @escaping (InitPayload) throws -> Void) {
9393
self.auth = callback
9494
}
9595

@@ -105,14 +105,14 @@ public class Server {
105105
self.onMessage = callback
106106
}
107107

108-
private func onConnectionInit(_ connectionInitRequest: ConnectionInitRequest) {
108+
private func onConnectionInit(_ connectionInitRequest: ConnectionInitRequest<InitPayload>) {
109109
guard !initialized else {
110110
self.error(.tooManyInitializations())
111111
return
112112
}
113113

114114
do {
115-
try self.auth(connectionInitRequest)
115+
try self.auth(connectionInitRequest.payload)
116116
}
117117
catch {
118118
self.error(.unauthorized())

Tests/GraphQLTransportWSTests/GraphQLTransportWSTests.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import XCTest
1111
class GraphqlTransportWSTests: XCTestCase {
1212
var clientMessenger: TestMessenger!
1313
var serverMessenger: TestMessenger!
14-
var server: Server!
14+
var server: Server<TokenInitPayload>!
1515

1616
override func setUp() {
1717
clientMessenger = TestMessenger()
@@ -24,7 +24,7 @@ class GraphqlTransportWSTests: XCTestCase {
2424
let api = TestAPI()
2525
let context = TestContext()
2626

27-
server = Server(
27+
server = Server<TokenInitPayload>(
2828
messenger: serverMessenger,
2929
onExecute: { graphQLRequest in
3030
api.execute(
@@ -48,7 +48,7 @@ class GraphqlTransportWSTests: XCTestCase {
4848
var messages = [String]()
4949
let completeExpectation = XCTestExpectation()
5050

51-
let client = Client(messenger: clientMessenger)
51+
let client = Client<TokenInitPayload>(messenger: clientMessenger)
5252
client.onMessage { message, _ in
5353
messages.append(message)
5454
completeExpectation.fulfill()
@@ -81,14 +81,14 @@ class GraphqlTransportWSTests: XCTestCase {
8181
var messages = [String]()
8282
let completeExpectation = XCTestExpectation()
8383

84-
let client = Client(messenger: clientMessenger)
84+
let client = Client<TokenInitPayload>(messenger: clientMessenger)
8585
client.onMessage { message, _ in
8686
messages.append(message)
8787
completeExpectation.fulfill()
8888
}
8989

9090
client.sendConnectionInit(
91-
payload: ConnectionInitAuth(
91+
payload: TokenInitPayload(
9292
authToken: ""
9393
)
9494
)
@@ -107,7 +107,7 @@ class GraphqlTransportWSTests: XCTestCase {
107107
var messages = [String]()
108108
let completeExpectation = XCTestExpectation()
109109

110-
let client = Client(messenger: clientMessenger)
110+
let client = Client<TokenInitPayload>(messenger: clientMessenger)
111111
client.onConnectionAck { _, client in
112112
client.sendStart(
113113
payload: GraphQLRequest(
@@ -131,7 +131,7 @@ class GraphqlTransportWSTests: XCTestCase {
131131
}
132132

133133
client.sendConnectionInit(
134-
payload: ConnectionInitAuth(
134+
payload: TokenInitPayload(
135135
authToken: ""
136136
)
137137
)
@@ -154,7 +154,7 @@ class GraphqlTransportWSTests: XCTestCase {
154154
var dataIndex = 1
155155
let dataIndexMax = 3
156156

157-
let client = Client(messenger: clientMessenger)
157+
let client = Client<TokenInitPayload>(messenger: clientMessenger)
158158
client.onConnectionAck { _, client in
159159
client.sendStart(
160160
payload: GraphQLRequest(
@@ -191,7 +191,7 @@ class GraphqlTransportWSTests: XCTestCase {
191191
}
192192

193193
client.sendConnectionInit(
194-
payload: ConnectionInitAuth(
194+
payload: TokenInitPayload(
195195
authToken: ""
196196
)
197197
)

0 commit comments

Comments
 (0)