Migrating to v1
One of the big goal of v1 is to bring fully bring a stable release of Pioneer with all the features and changes added in the past year, and allow Pioneer to be more customisable, and more compatible with more server-side Swift frameworks and libraries.
Decoupling from Vapor
Pioneer also now no longer a Vapor (opens in a new tab)-only library and exposes more of its internal functions, structs, protocols, and classes which will allow integrations with other web frameworks.
Middleware
Pioneer will no longer add routes to a Vapor (opens in a new tab) Application with the .applyMiddleware
function.
Instead, Pioneer will have a Vapor (opens in a new tab) integration module that extends Pioneer (opens in a new tab) with VaporGraphQLMiddleware (opens in a new tab) which can be use like a regular Vapor (opens in a new tab) middleware.
let app = try Application(.detect())
let server = Pioneer(
schema: schema,
resolver: resolver
)
app.middleware.use(server.vaporMiddleware())
Context Builder
Alongside being a middleware, all context builder and guard functions are passed into the middleware instead of directly to Pioneer. This allow Pioneer be decoupled from Vapor but still allow integration with Vapor's Request
and Response
in the context builder.
let server = Pioneer(
schema: schema,
resolver: resolver
)
app.middleware.use(
server.vaporMiddleware(
context: { req, res in
...
},
websocketContext: { req, payload, gql in
...
}
)
)
WebSocket Guard
Pioneer now properly implement a WebSocket initialisation guard, which will fire for each new GraphQL over WebSocket connection that initialise properly. This allow user configured authorization of each WebSocket connection.
let server = Pioneer(
schema: schema,
resolver: resolver
)
app.middleware.use(
server.vaporMiddleware(
context: { req, res in
...
},
websocketContext: { req, payload, gql in
...
},
websocketGuard: { req, payload in
...
}
)
)
Same path for all
Pioneer v0 uses 3 different paths for GraphQL over HTTP, GraphQL over WebSocket, and GraphQL IDE hosting.
In v1, Pioneer will use the same path for all of those, and will instead determine from the request whether is a GraphQL over HTTP request, a GraphQL over WebSocket upgrade request, or a GraphQL IDE request.
Standalone server
Pioneer will also now include option to run standalone.
let server = Pioneer(
schema: schema,
resolver: resolver
)
try server.standaloneServer(
context: { req, res in
...
},
websocketContext: { req, payload, gql in
...
},
websocketGuard: { req, payload in
...
}
)
Under the hood, the standalone server uses the Vapor integration.
Other changes
New defaults
Pioneer will now defaults to
- .csrfPrevention (opens in a new tab) for its HTTPStrategy
- .graphqlWs (opens in a new tab) for its WebSocket Protocol
- .sandbox (opens in a new tab) for its GraphQL IDE
30
seconds for the keep alive interval for GraphQL over WebSocket
Deprecating subscriptions-transport-ws
As of Mar 4 2022, the subscriptions-transport-ws (opens in a new tab) has been made read-only archive and will be marked as deprecated in Pioneer.
Pioneer will now defaults to the graphql-ws
instead.
WebSocket callbacks
Some WebSocket callbacks are now exposed as functions in Pioneer. These can be used to add a custom WebSocket layer.
- .receiveMessage (opens in a new tab)
- Callback to be called for each WebSocket message
- .createClient (opens in a new tab)
- Callback after getting a GraphQL over WebSocket initialisation message according to the given protocol
- .executeLongOperation (opens in a new tab)
- Callback to run long running operation using Pioneer
- .executeShortOperation (opens in a new tab)
- Callback to run short lived operation using Pioneer
Pioneer capabilities
Some other capabilities of Pioneer is now exposed:
-
.allowed (opens in a new tab), Check if a GraphQL request is allowed given the allowed list of operations
-
.csrfVulnerable (opens in a new tab), Check if the headers given show signs of CSRF and XS-Search vulnerability
-
.executeHTTPGraphQLRequest (opens in a new tab), Execute an operation for a given HTTPGraphQLRequest (opens in a new tab) and returns HTTPGraphQLResponse (opens in a new tab)
ConnectionParams to Payload
The type ConnectionParams
is renamed to Payload
typealias Payload = [String: Map]?