Skip to content

Commit

Permalink
Merge pull request #7 from d-exclaimation/graphql-swift
Browse files Browse the repository at this point in the history
GraphQLSchema Migration, GraphQL Playground
  • Loading branch information
d-exclaimation authored Dec 10, 2021
2 parents caadbe2 + 6e3fa7a commit 208a437
Show file tree
Hide file tree
Showing 43 changed files with 530 additions and 189 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
/.swiftpm
/.idea
/.build-docs
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fd-exclaimation%2Fpioneer%2Fbadge%3Ftype%3Dswift-versions&style=for-the-badge)](https://swiftpackageindex.com/d-exclaimation/pioneer)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fd-exclaimation%2Fpioneer%2Fbadge%3Ftype%3Dplatforms&style=for-the-badge)](https://swiftpackageindex.com/d-exclaimation/pioneer)

Pioneer is a open-source Swift GraphQL server, for Vapor. Pioneer works with any GraphQL schema built with [Graphiti](https://github.com/GraphQLSwift/Graphiti).
Pioneer is a open-source Swift GraphQL server, for Vapor. Pioneer works with any GraphQL schema built with [GraphQL](https://github.com/GraphQLSwift/GraphQL).

## Getting Started

An overview of GraphQL in general is available in the [README](https://github.com/facebook/graphql/blob/master/README.md) for the [Specification for GraphQL](https://github.com/facebook/graphql). An overview of Graphiti is also described in the package's [README](https://github.com/GraphQLSwift/Graphiti/blob/master/README.md).
An overview of GraphQL in general is available in the [README](https://github.com/facebook/graphql/blob/master/README.md) for the [Specification for GraphQL](https://github.com/facebook/graphql). We will be using Graphiti as the GraphQL schema library for this basic implementation. An overview of Graphiti is also described in the package's [README](https://github.com/GraphQLSwift/Graphiti/blob/master/README.md).

### Using Pioneer

Expand All @@ -25,8 +25,18 @@ import PackageDescription
let package = Package(
dependencies: [
.package(url: "https://github.com/GraphQLSwift/Graphiti.git", from: "1.0.0"),
.package(url: "https://github.com/vapor/vapor.git", from: "4.53.0"),
.package(url: "https://github.com/d-exclaimation/pioneer", from: "0.1.3")
.package(url: "https://github.com/vapor/vapor.git", from: "4.54.0"),
.package(url: "https://github.com/d-exclaimation/pioneer", from: "0.1.4")
],
targets: [
.target(
name: "MyGraphQLServer",
dependencies: [
.product(name: "Pioneer", package: "pioneer"),
.product(name: "Graphiti", package: "Graphiti"),
.product(name: "Vapor", package: "vapor")
]
)
]
)
```
Expand Down Expand Up @@ -112,7 +122,7 @@ let stream = MyAsyncSequence<Message>(...)

stream.toEventStream(
// Require here as it cannot access `AsyncStream.Continuation.onTermination`
onTermination: {
onTermination: { _ in
// deallocate resources
}
)
Expand Down Expand Up @@ -213,7 +223,7 @@ schema {

### Integrating Pioneer, Graphiti, and Vapor

Setting up the server would be fairly straight forward
Setting up the server would be fairly straight forward. We will be supplying the `contextBuilder` directly, using the websocket sub-protocol `subscriptions-transport-ws`, and allowing introspection.

```swift
import Vapor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Pioneer
//
// Created by d-exclaimation on 11:38 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand All @@ -28,4 +27,4 @@ extension Dictionary {
guard let _ = self[key] else { return false }
return true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Pioneer
//
// Created by d-exclaimation on 4:33 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand All @@ -18,4 +17,4 @@ extension OrderedDictionary {
}
return res
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Pioneer
//
// Created by d-exclaimation on 11:41 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand Down Expand Up @@ -46,4 +45,4 @@ extension AsyncSequence {
}
}
}
}
}
39 changes: 39 additions & 0 deletions Sources/Pioneer/Extensions/Pioneer+Graphiti.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Pioneer+Graphiti.swift
// Pioneer
//
// Created by d-exclaimation on 9:46 PM.
//

import Graphiti
import Vapor

public extension Pioneer {
/// - Parameters:
/// - schema: GraphQL schema used to execute operations
/// - resolver: Resolver used by the GraphQL schema
/// - contextBuilder: Context builder from request
/// - httpStrategy: HTTP strategy
/// - websocketProtocol: Websocket sub-protocol
/// - introspection: Allowing introspection
/// - playground: Allowing playground
init(
schema: Schema<Resolver, Context>,
resolver: Resolver,
contextBuilder: @escaping (Request, Response) -> Context,
httpStrategy: HTTPStrategy = .queryOnlyGet,
websocketProtocol: WebsocketProtocol = .subscriptionsTransportWs,
introspection: Bool = true,
playground: Bool = true
) {
self.init(
schema: schema.schema,
resolver: resolver,
contextBuilder: contextBuilder,
httpStrategy: httpStrategy,
websocketProtocol: websocketProtocol,
introspection: introspection,
playground: playground
)
}
}
61 changes: 6 additions & 55 deletions Sources/Pioneer/Extensions/Pioneer+RequestContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,35 @@
// Pioneer
//
// Created by d-exclaimation on 9:46 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
import Vapor
import Graphiti

public extension Pioneer where Context == Request {
/// - Parameters:
/// - schema: Graphiti schema used to execute operations
/// - resolver: Resolver used by the GraphQL schema
/// - httpStrategy: HTTP strategy
/// - websocketProtocol: Websocket sub-protocol
/// - introspection: Allowing introspection
init(
schema: Schema<Resolver, Request>,
resolver: Resolver,
httpStrategy: HTTPStrategy = .queryOnlyGet,
websocketProtocol: WebsocketProtocol = .subscriptionsTransportWs,
introspection: Bool = true
) {
self.init(
schema: schema,
resolver: resolver,
contextBuilder: { req, _ in req },
httpStrategy: httpStrategy,
websocketProtocol: websocketProtocol,
introspection: introspection
)
}
}

public extension Pioneer where Context == Void {
/// - Parameters:
/// - schema: Graphiti schema used to execute operations
/// - resolver: Resolver used by the GraphQL schema
/// - httpStrategy: HTTP strategy
/// - websocketProtocol: Websocket sub-protocol
/// - introspection: Allowing introspection
/// - playground: Allowing playground
init(
schema: Schema<Resolver, Void>,
resolver: Resolver,
httpStrategy: HTTPStrategy = .queryOnlyGet,
websocketProtocol: WebsocketProtocol = .subscriptionsTransportWs,
introspection: Bool = true
introspection: Bool = true,
playground: Bool = true
) {
self.init(
schema: schema,
schema: schema.schema,
resolver: resolver,
contextBuilder: { _, _ in },
httpStrategy: httpStrategy,
websocketProtocol: websocketProtocol,
introspection: introspection
introspection: introspection,
playground: playground
)
}
}

public extension Pioneer where Context == (Request, Response) {
/// - Parameters:
/// - schema: Graphiti schema used to execute operations
/// - resolver: Resolver used by the GraphQL schema
/// - httpStrategy: HTTP strategy
/// - websocketProtocol: Websocket sub-protocol
/// - introspection: Allowing introspection
init(
schema: Schema<Resolver, (Request, Response)>,
resolver: Resolver,
httpStrategy: HTTPStrategy = .queryOnlyGet,
websocketProtocol: WebsocketProtocol = .subscriptionsTransportWs,
introspection: Bool = true
) {
self.init(
schema: schema,
resolver: resolver,
contextBuilder: { ($0, $1) },
httpStrategy: httpStrategy,
websocketProtocol: websocketProtocol,
introspection: introspection
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Pioneer
//
// Created by d-exclaimation on 10:55 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand All @@ -15,4 +14,4 @@ extension Data {
decoder.dateDecodingStrategy = .iso8601
return try? decoder.decode(T.self, from: self)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
// Pioneer
//
// Created by d-exclaimation on 11:02 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
import GraphQL
import Vapor

extension GraphQLResult: Content {}
extension GraphQLResult: Content {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// CORSMiddleware+BananaCakePop.swift
// Pioneer
//
// Created by d-exclaimation.
//

import Vapor
import NIOHTTP1

extension CORSMiddleware.Configuration {
/// Setup CORS for GraphQL allowing Banana Cake Pop GraphQL IDE (Cloud Version)
///
/// - Parameter urls: Extra Allowed origins
/// - Returns: CORS Configuration
public static func graphqlWithBananaCakePop(with urls: [String] = []) -> CORSMiddleware.Configuration {
let allowedOrigin: CORSMiddleware.AllowOriginSetting = .any(["https://eat.bananacakepop.com/"] + urls)
let allowedMethods: [HTTPMethod] = [.GET, .POST, .OPTIONS]
let allowedHeaders: [HTTPHeaders.Name] = [
.secWebSocketProtocol, .accept, .authorization, .contentType, .origin, .userAgent, .accessControlAllowOrigin, .xRequestedWith
]
return .init(allowedOrigin: allowedOrigin, allowedMethods: allowedMethods, allowedHeaders: allowedHeaders)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//
// CORSMiddleware+ApolloSandbox.swift
// pioneer-integration-test
// Pioneer
//
// Created by d-exclaimation on 3:32 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand All @@ -23,4 +22,4 @@ extension CORSMiddleware.Configuration {
]
return .init(allowedOrigin: allowedOrigin, allowedMethods: allowedMethods, allowedHeaders: allowedHeaders)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//
// EnvironmentVariables.swift
// pioneer-integration-test
// Pioneer
//
// Created by d-exclaimation on 3:32 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand Down
1 change: 0 additions & 1 deletion Sources/Pioneer/GraphQL/BuiltinTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// pioneer-integration-test
//
// Created by d-exclaimation on 3:59 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Foundation
Expand Down
3 changes: 1 addition & 2 deletions Sources/Pioneer/GraphQL/Extensions/Field+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Pioneer
//
// Created by d-exclaimation on 4:38 PM.
// Copyright © 2021 d-exclaimation. All rights reserved.
//

import Graphiti
Expand Down Expand Up @@ -218,4 +217,4 @@ extension EventLoopGroup {
}
return promise.futureResult
}
}
}
Loading

0 comments on commit 208a437

Please sign in to comment.