I'm trying to get a GraphQL subscription from SoundtrackYourBrand working within my iOS app. The queries/mutations work fine but when I use the web socket I get either error 400 or 403 ("Invalid HTTP upgrade") or 1011 (no message) depending on how I've set the authorisation token.
Error WebSocketError(payload: nil, error: Optional(Starscream.WSError(type: Starscream.ErrorType.upgradeError, message: "Invalid HTTP upgrade", code: 403)), kind: ApolloWebSocket.WebSocketError.ErrorKind.networkError)
Error WebSocketError(payload: nil, error: Optional(Starscream.WSError(type: Starscream.ErrorType.protocolError, message: "", code: 1011)), kind: ApolloWebSocket.WebSocketError.ErrorKind.networkError)
I'm using Apollo to work with the graphQL API. And it works for mutations/queries. I've set up a splitNetwork Transport as per the Apollo docs here.
var wssURL: String = "wss://api.soundtrackyourbrand.com/v2"
client = {
let request = URLRequest(url: wssURL)
let authPayload = ["Authorization" : "Bearer \(token)"]
let webSocketTransport = WebSocketTransport(request: request, connectingPayload: authPayload)
let client = URLSessionClient()
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let provider = NetworkInterceptorProvider(store: store, client: client)
let normalTransport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: endpointURL, additionalHeaders: ["authorization" : "Bearer \(token)"])
let splitNetworkTransport = SplitNetworkTransport(
uploadingNetworkTransport: normalTransport,
webSocketNetworkTransport: webSocketTransport
)
return ApolloClient(networkTransport: splitNetworkTransport, store: store)
}()
While above is the way Apollo suggests doing authorisation, in the SoundtrackYourbrand docs it says set the token as a query parameter: "You won't be using any headers, so the token need to be passed as a query parameter."
In which case should I set up the websocket like below.
The below code gives me the protocol error 1011, while the above code gives the 400/403 "Invalid HTTP upgrade" error.
client = {
let queryItems = [URLQueryItem(name: "Authorization", value: "Bearer \(token)")]
var urlComps = URLComponents(string: wssURL)!
urlComps.queryItems = queryItems
let result = urlComps.url!
let request = URLRequest(url: result)
let webSocketTransport = WebSocketTransport(request: request)
let client = URLSessionClient()
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let provider = NetworkInterceptorProvider(store: store, client: client)
let normalTransport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: endpointURL, additionalHeaders: ["authorization" : "Bearer \(token)"])
let splitNetworkTransport = SplitNetworkTransport(
uploadingNetworkTransport: normalTransport,
webSocketNetworkTransport: webSocketTransport
)
return ApolloClient(networkTransport: splitNetworkTransport, store: store)
}()
Also should my starting URL be:
- wss://api.soundtrackyourbrand.com/v2
- wss://api.soundtrackyourbrand.com/v2/websocket
Looking at the docs I would think it should be 2), but after getting a subscription working in the SoundtrackYourbrand workspace, which uses 1) I assume I must use 1).
In the workspace I use the WS URL provided by default: wss://api.soundtrackyourbrand.com/v2, and then set the authorisation header to "Bearer ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••...". And that works, but can't seem to replicate it in the iOS app with Apollo
What am I doing wrong?
Any help would be greatly appreciated!