Closed d-exclaimation closed 1 year ago
A draft on how I could do the second approach:
import enum GraphQL.Map
import class JSONEncoder
import class JSONDecoder
extension Map {
public func into<T: Decodable>(_ dataType: T.Type) throws -> T {
let data = try JSONEncoder().encode(self)
return try JSONDecoder().decode(dataType, from: data)
}
}
// ...
server.vaporMiddleware(
websocketContext: { req, payload, gql in
let myPayload = payload.into(MyPayload.self)
// do something with it
}
)
With this I can have somewhat implement the first with
public typealias VaporCustomWebSocketContext<P: Decodable> = @Sendable (Request, P, GraphQLRequest) async throws -> Context
public typealias VaporCustomWebSocketGuard<P: Decodable> = @Sendable (Request, P) async throws -> Void
public func vaporMiddleware<CustomPayload: Decodable>(
...,
websocketContext: VaporCustomWebSocketContext<CustomPayload>,
websocketGuard: VaporCustomWebSocketGuard<CustomPayload>
) -> VaporGraphQLMiddleware {
vaporMiddleware(
...,
websocketContext: { req, payload, gql in
let custom = payload.into(CustomPayload.self)
return try await websocketContext(req, custom, gql)
},
websocketGuard: { req, payload in
let custom = payload.into(CustomPayload.self)
return try await websocketGuard(req, custom)
}
)
}
I am not particularly a big fan of the above, as I feel if I were to do the first, I need to somewhat rewrite the WebSocket client so that it doesn't have to re-parse the payload for each websocket operation, maybe that advantage of the websocket guard to compute the payload object.
I think the best way is to implement the Map.into(_)
first and later see if I can do the first without adding breaking changes
Is your feature request related to a problem? Please describe. It's not a pleasant experience having to work with
Map
for the WebSocket payload, especially if the user already know what to expect.Describe the solution you'd like 2 approach:
Map
with functionalities to be parsed to other types