Skip to content

Commit

Permalink
Merge pull request #91 from d-exclaimation/async-event-stream-plus
Browse files Browse the repository at this point in the history
AsyncEventStream convenience initialisers, Embedded Sandbox as default
  • Loading branch information
d-exclaimation authored Oct 31, 2022
2 parents 7364824 + 2d45b6a commit addc783
Show file tree
Hide file tree
Showing 30 changed files with 230 additions and 1,374 deletions.
10 changes: 5 additions & 5 deletions Documentation/features/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ order: 50
# Configuration

!!!success Custom Configuration options
From `0.9.3`, Pioneer brought in a structure that will allow easier configuration, which would only require you to pass in the config object into [Pioneer](/references/pioneer) initializer.
From `0.9.3`, Pioneer brought in a structure that will allow easier configuration, which would only require you to pass in the config object into [Pioneer](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer) initializer.
!!!

This configuration structure would allow user of the library to create multiple configuration for Pioneer on different environment or situation.

## Config

The Config object takes in all the parameters required to initialized a [Pioneer](/references/pioneer) server instance.
The Config object takes in all the parameters required to initialized a [Pioneer](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer) server instance.

```swift
let server = Pioneer(
.init(...)
)
```

_You are still allowed to directly passed in the required parameters for [Pioneer](/references/pioneer) into its initializer without the use of configs._
_You are still allowed to directly passed in the required parameters for [Pioneer](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer) into its initializer without the use of configs._

## Built-in configs

Expand Down Expand Up @@ -147,7 +147,7 @@ let server = Pioneer(
Context(req, res)
},
httpStrategy: .csrfPrevention,
playground: .graphiql
playground: .sandbox
)
)
```
Expand Down Expand Up @@ -210,7 +210,7 @@ let server = Pioneer(
Context(req, payload, gql)
},
websocketProtocol: .graphqlWs,
playground: .graphiql
playground: .sandbox
)
)
```
Expand Down
100 changes: 45 additions & 55 deletions Documentation/features/graphql-ide.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,53 @@ GraphQL IDEs are quick and convenient ways to develop and test your GraphQL APIs
Pioneer will disable any GraphQL IDE automatically regardless of the specified parameter, if introspection is disabled, as GraphQL IDE relies on introspection to provide syntax highlighting.
!!!

## Apollo Sandbox

Apollo Sandbox is in browser GraphQL IDE developed by Apollo GraphQL and their choice of replacement for [GraphQL Playground](#graphql-playground). Apollo Sandbox provide all features available in [GraphQL Playground](#graphql-playground) and a lot more.

![](/static/sandbox.jpeg)

Pioneer can provide 2 option for setting up Apollo Sandbox:

+++ Embedded

Embedded version of Apollo Sandbox served similarly to [GraphiQL](#graphiql) without needing to setup CORS.

```swift
let server = Pioneer(
...,
playground: .sandbox
)

server.applyMiddleware(on: app)
```

+++ Cloud Redirect

Redirecting route (at [/playground](http://localhost:8080/playground)) to Apollo Sandbox and a `CORSMiddleware.Configuration` for the purpose of allowing Apollo Sandbox through CORS.

```swift
let server = Pioneer(
...,
playground: .apolloSandbox // or .redirect(to: .apolloSandbox)
)
let cors = CORSMiddleware(configuration: .graphqlWithApolloSandbox())

app.middleware.use(cors, at: .beginning)

server.applyMiddleware(on: app)
```

<sub>You can also just set this up on your own</sub>

+++

Afterwards, you can go to [./playground](http://localhost:8080/playground) to open a instance of Apollo Sandbox whether it is the cloud or the locally embedded version.


## GraphiQL

GraphiQL is the official GraphQL IDE by the GraphQL Foundation. The current GraphiQL version has met feature parody with [GraphQL Playground](#graphql-playground) (\*mostly).
GraphiQL is the official GraphQL IDE by the GraphQL Foundation. The current GraphiQL version has met feature parity with [GraphQL Playground](#graphql-playground) (\*mostly).

![](/static/graphiql.png)

Expand Down Expand Up @@ -71,60 +115,6 @@ WebSocket /graphql/websocket
GET /playground # (For playground)
```

## Apollo Sandbox

Apollo Sandbox is a cloud hosted in browser GraphQL IDE developed by Apollo GraphQL and their choice of replacement for [GraphQL Playground](#graphql-playground). Apollo Sandbox provide all features available in [GraphQL Playground](#graphql-playground) and a lot more. However, this is either:

- A cloud based solution that require CORS configuration and cannot be self-hosted, or
- A locally embedded solution that limited capabilities compared to the cloud version.

Both solutions is not open source.

![](/static/sandbox.jpeg)

Pioneer can provide 2 option for setting up Apollo Sandbox:

+++ Cloud Redirect (Preffered)

Redirecting route (at [/playground](http://localhost:8080/playground)) to Apollo Sandbox and a `CORSMiddleware.Configuration` for the purpose of allowing Apollo Sandbox through CORS.

```swift
let server = Pioneer(
...,
playground: .apolloSandbox // or .redirect(to: .apolloSandbox)
)
let cors = CORSMiddleware(configuration: .graphqlWithApolloSandbox())

app.middleware.use(cors, at: .beginning)

server.applyMiddleware(on: app)
```

<sub>You can also just set this up on your own</sub>

+++ Embedded Locally

Embedded version of Apollo Sandbox served similarly to [GraphiQL](#graphiql) without needing to setup CORS.

```swift
let server = Pioneer(
...,
playground: .sandbox
)

server.applyMiddleware(on: app)
```

!!!warning Limited
The embedded version of [Apollo Sandbox](https://www.apollographql.com/docs/studio/explorer/sandbox/#embedding-sandbox) has some limitation notably the lack of subscription support that is available for the regular [Sandbox](https://studio.apollographql.com/sandbox/explorer).

Given that, the preffered / default option for `apolloSandbox` is the redirect option.
!!!

+++

Afterwards, you can go to [./playground](http://localhost:8080/playground) to open a instance of Apollo Sandbox whether it is the cloud or the locally embedded version.

## Banana Cake Pop

Banana Cake Pop is both a cloud hosted in browser and a downloable application GraphQL IDE developed by people over at [ChilliCream](https://chillicream.com/). Banana Cake Pop provide all features available in [GraphQL Playground](#graphql-playground) and a few more. However when using the cloud based solution, you required to specify a CORS configuration similar to [Apollo Sandbox](#apollo-sandbox).
Expand Down
6 changes: 3 additions & 3 deletions Documentation/features/graphql-over-http.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ If either of these apply to you and you want to keep the prevention mechanic, yo

## Manual HTTP Routing

In cases where the routing configuration by Pioneer when using [`.applyMiddleware`](/references/pioneer/#applymiddleware) is insufficient to your need, you can opt out and manually set your routes, have Pioneer still handle GraphQL operation, and even execute code on the incoming request before Pioneer handles the GraphQL operation(s).
In cases where the routing configuration by Pioneer when using [`.applyMiddleware`](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/applymiddleware(on:at:bodystrategy:)) is insufficient to your need, you can opt out and manually set your routes, have Pioneer still handle GraphQL operation, and even execute code on the incoming request before Pioneer handles the GraphQL operation(s).

To do that, you can utilize the newly added [`.httpHandler(req:)`](/references/pioneer/#httphandler) method from Pioneer, which will handle incoming `Request` and return a proper GraphQL formatted`Response`.
To do that, you can utilize the newly added [`.httpHandler(req:)`](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/httphandler(req:)) method from Pioneer, which will handle incoming `Request` and return a proper GraphQL formatted`Response`.

!!!success Manual WebSocket Routing
Pioneer also provide handler to manually setting routes for WebSocket
Expand Down Expand Up @@ -217,7 +217,7 @@ app.group("api") {

### Consideration

The [`.httpHandler(req:)`](/references/pioneer/#httphandler) method has some behavior to be aware about. Given that it is a method from the Pioneer struct, it still uses the configuration set when creating the Pioneer server, such as:
The [`.httpHandler(req:)`](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/httphandler(req:)) method has some behavior to be aware about. Given that it is a method from the Pioneer struct, it still uses the configuration set when creating the Pioneer server, such as:

1. It will still use the [HTTPStrategy](#http-strategy) and check if the request is valid / allowed to go through.
- For example, if you set a **GET** route using this but the httpStrategy is set to `.onlyPost`, this handler won't accept **GET** request for all GraphQL operations and will just throw an error.
Expand Down
6 changes: 3 additions & 3 deletions Documentation/features/graphql-over-websocket.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ Any operation going through websocket uses the websocket context builder instead

## Manual WebSocket Routing

In cases where the routing configuration by Pioneer when using [`.applyMiddleware`](/references/pioneer/#applymiddleware) is insufficient to your need, you can opt out and manually set your routes, have Pioneer still handle GraphQL operation, and even execute code on the incoming request before Pioneer handles the GraphQL operation(s).
In cases where the routing configuration by Pioneer when using [`.applyMiddleware`](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/applymiddleware(on:at:bodystrategy:)) is insufficient to your need, you can opt out and manually set your routes, have Pioneer still handle GraphQL operation, and even execute code on the incoming request before Pioneer handles the GraphQL operation(s).

To do that, you can utilize the newly added [`.webSocketHandler(req:)`](/references/pioneer/#websockethandler) method from Pioneer, which will handle incoming `Request`, upgrade to WebSocket, and handle WebSocket messages as well.
To do that, you can utilize the newly added [`.webSocketHandler(req:)`](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/websockethandler(req:)) method from Pioneer, which will handle incoming `Request`, upgrade to WebSocket, and handle WebSocket messages as well.

!!!success Manual HTTP Routing
Pioneer also provide handler to manually setting routes for HTTP
Expand Down Expand Up @@ -119,7 +119,7 @@ app.group("api") {

### Consideration

The [`.webSocketHandler(req:)`](/references/pioneer/#websockethandler) method has some behavior to be aware about. Given that it is a method from the Pioneer struct, it still uses the configuration set when creating the Pioneer server, such as:
The [`.webSocketHandler(req:)`](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/websockethandler(req:)) method has some behavior to be aware about. Given that it is a method from the Pioneer struct, it still uses the configuration set when creating the Pioneer server, such as:

- It will still use the [WebsocketProtocol](#websocket-subprotocol) and check if the upgrade request is valid / allowed to go through.
- For example, this handler won't accept **GET** request and perform the upgrade to WebSocket if the provided `Sec-Websocket-Protocol` header value does not match the required value for each websocket subprotocol.
8 changes: 4 additions & 4 deletions Documentation/guides/advanced/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ let server = Pioneer(
contextBuilder: getContext,
websocketProtocol: .graphqlWs,
introspection: true,
playground: .graphiql
playground: .sandbox
)
```

Expand Down Expand Up @@ -107,7 +107,7 @@ let server = Pioneer(
websocketContextBuilder: getWebsocketContext,
websocketProtocol: .graphqlWs,
introspection: true,
playground: .graphiql
playground: .sandbox
)
```

Expand Down Expand Up @@ -208,7 +208,7 @@ struct Resolver {
}
```

[!ref GraphQLRequest API References](/references/structs/#graphqlrequest)
[!ref GraphQLRequest API References](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/graphqlrequest)

## WebSocket Initialisation Hook and Authorization

Expand All @@ -231,6 +231,6 @@ let server = Pioneer(
},
websocketProtocol: .graphqlWs,
introspection: true,
playground: .graphiql
playground: .sandbox
)
```
18 changes: 9 additions & 9 deletions Documentation/guides/advanced/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ Yes. Pioneer have extensions for Graphiti, but it works with any schema librarie

### Scalars

#### Does the [ID](/references/structs/#id) field worked with `UUID` and/or Fluent?
#### Does the [ID](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/id) field worked with `UUID` and/or Fluent?

Yes. The [ID](/references/structs/#id) is just a wrapper around string used to help Graphiti differentiate between `String` to an `ID` from GraphQL built in scalars.
Yes. The [ID](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/id) is just a wrapper around string used to help Graphiti differentiate between `String` to an `ID` from GraphQL built in scalars.

!!!success UUID to ID extension
Since `0.8.3`, you can call the method `.toID()` or use the computed property `.id` to turn any `UUID` or `String` into an [ID](/references/structs/#id).
Since `0.8.3`, you can call the method `.toID()` or use the computed property `.id` to turn any `UUID` or `String` into an [ID](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/id).
!!!

`UUID` can be easily parsed back into a string and used for making [ID](/references/structs/#id).
`UUID` can be easily parsed back into a string and used for making [ID](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/id).

[!ref ID and UUID](/guides/advanced/fluent/#graphql-id)

Expand Down Expand Up @@ -189,12 +189,12 @@ Yes, [ConcurrentEventStream](https://github.com/GraphQLSwift/GraphQL/blob/master

### PubSub

#### Does Pioneer provide an [AsyncPubSub](/references/async-pubsub.md) that is backed by Redis?
#### Does Pioneer provide an [AsyncPubSub](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/async-pubsub.md) that is backed by Redis?

No, Pioneer only provide [AsyncPubSub](/references/async-pubsub.md), the in-memory implementation [PubSub](/references/protocols/#pubsub). However, Pioneer does export the [PubSub](/references/protocols/#pubsub) protocol to allow custom implemenation that have similar API with [AsyncPubSub](/references/async-pubsub.md).
No, Pioneer only provide [AsyncPubSub](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/async-pubsub.md), the in-memory implementation [PubSub](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pubsub). However, Pioneer does export the [PubSub](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pubsub) protocol to allow custom implemenation that have similar API with [AsyncPubSub](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/async-pubsub.md).

!!!success RedisPubSub
Implementation of Redis backed [PubSub](/references/protocols/#pubsub) is available under the package [PioneerRedisPubSub](https://github.com/d-exclaimation/pioneer-redis-pubsub). Alternatively, you could build your own implementation using this [example](/guides/advanced/subscriptions/#redis-example) as a starting point.
Implementation of Redis backed [PubSub](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pubsub) is available under the package [PioneerRedisPubSub](https://github.com/d-exclaimation/pioneer-redis-pubsub). Alternatively, you could build your own implementation using this [example](/guides/advanced/subscriptions/#redis-example) as a starting point.
!!!

[!ref PubSub as a protocol](/guides/advanced/subscriptions/#pubsub-as-protocol)
Expand All @@ -205,15 +205,15 @@ Implementation of Redis backed [PubSub](/references/protocols/#pubsub) is availa

#### Can I opt out from Pioneer's routing and set my own routes, while still have Pioneer handle all HTTP request?

Yes, you can using the [httpHandler(req:)](/references/pioneer/#httphandler). In which, you can perform code before and after the GraphQL operation by the handler.
Yes, you can using the [httpHandler(req:)](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/httphandler(req:)). In which, you can perform code before and after the GraphQL operation by the handler.

[!ref Manual HTTP Routing](/features/graphql-over-http/#manual-http-routing)

### WebSocket

#### Can I opt out from Pioneer's routing and set my own routes, while still have Pioneer handle all WebSocket operations?

Yes, you can using the [webSocketHandler(req:)](/references/pioneer/#websockethandler). However different from HTTP, you can manually set the route only for the upgrade request, but you cannot intercept and manually handle WebSocket messages.
Yes, you can using the [webSocketHandler(req:)](https://swiftpackageindex.com/d-exclaimation/pioneer/documentation/pioneer/pioneer/websockethandler(req:)). However different from HTTP, you can manually set the route only for the upgrade request, but you cannot intercept and manually handle WebSocket messages.

[!ref Manual WebSocket Routing](/features/graphql-over-websocket/#manual-websocket-routing)

Expand Down
Loading

0 comments on commit addc783

Please sign in to comment.