Skip to content

Commit

Permalink
feat: Add ability to pass routes into configuration (#74)
Browse files Browse the repository at this point in the history
* feat: Add ability to pass routes into configuration

* lint
  • Loading branch information
cbaker6 committed Aug 4, 2024
1 parent 336b0d2 commit 7c11bd3
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 91 deletions.
20 changes: 10 additions & 10 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/async-kit.git",
"state" : {
"revision" : "7ece208cd401687641c88367a00e3ea2b04311f1",
"version" : "1.19.0"
"revision" : "e048c8ee94967e8d8a1c2ec0e1156d6f7fa34d31",
"version" : "1.20.0"
}
},
{
Expand All @@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/netreconlab/Parse-Swift.git",
"state" : {
"revision" : "48b38b15363846e0714bc632c1939f721f71f4b2",
"version" : "5.11.1"
"revision" : "b56de0a0770fb3ac267d3d8d1cc3924fbfbf3d16",
"version" : "5.11.2"
}
},
{
Expand Down Expand Up @@ -122,8 +122,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "fc79798d5a150d61361a27ce0c51169b889e23de",
"version" : "2.68.0"
"revision" : "e4abde8be0e49dc7d66e6eed651254accdcd9533",
"version" : "2.69.0"
}
},
{
Expand All @@ -140,8 +140,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "a0224f3d20438635dd59c9fcc593520d80d131d0",
"version" : "1.33.0"
"revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
"version" : "1.34.0"
}
},
{
Expand Down Expand Up @@ -176,8 +176,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "6a9e38e7bd22a3b8ba80bddf395623cf68f57807",
"version" : "1.3.1"
"revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5",
"version" : "1.3.2"
}
},
{
Expand Down
20 changes: 12 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.6
// swift-tools-version:5.7
import PackageDescription

// swiftlint:disable line_length
Expand All @@ -21,11 +21,11 @@ let package = Package(
dependencies: [
.package(
url: "https://github.com/vapor/vapor.git",
.upToNextMajor(from: "4.102.1")
.upToNextMajor(from: "4.102.1")
),
.package(
url: "https://github.com/netreconlab/Parse-Swift.git",
.upToNextMajor(from: "5.11.1")
.upToNextMajor(from: "5.11.2")
)
],
targets: [
Expand All @@ -43,10 +43,14 @@ let package = Package(
// the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
// builds. See <https://github.com/swift-server/guides/blob/main/docs/building.md#building-for-production> for details.
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
]),
.testTarget(name: "ParseServerSwiftTests", dependencies: [
.target(name: "ParseServerSwift"),
.product(name: "XCTVapor", package: "vapor")
])
]
),
.testTarget(
name: "ParseServerSwiftTests",
dependencies: [
.target(name: "ParseServerSwift"),
.product(name: "XCTVapor", package: "vapor")
]
)
]
)
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ enum Entrypoint {
let executorTakeoverSuccess = NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor()
app.logger.debug("Running with \(executorTakeoverSuccess ? "SwiftNIO" : "standard") Swift Concurrency default executor")

try await parseServerSwiftConfigure(app)
try await parseServerSwiftConfigure(
app,
using: exampleRoutes
)
try await app.execute()
try await app.asyncShutdown()
}
Expand Down
5 changes: 4 additions & 1 deletion Sources/App/entrypoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ enum Entrypoint {
"Running with \(executorTakeoverSuccess ? "SwiftNIO" : "standard") Swift Concurrency default executor"
)

try await parseServerSwiftConfigure(app)
try await parseServerSwiftConfigure(
app,
using: exampleRoutes
)
try await app.execute()
try await app.asyncShutdown()
}
Expand Down
43 changes: 27 additions & 16 deletions Sources/ParseServerSwift/Parse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,42 +30,53 @@ public var configuration: ParseServerConfiguration {
server URL.
- warning: Be sure to call this method before calling `try routes(app)`.
*/
public func initialize(_ configuration: ParseServerConfiguration,
app: Application) async throws {
public func initialize(
_ configuration: ParseServerConfiguration,
app: Application
) async throws {
try await initializeServer(configuration, app: app)
}

func initialize(_ configuration: ParseServerConfiguration,
app: Application,
testing: Bool) async throws {
func initialize(
_ configuration: ParseServerConfiguration,
app: Application,
testing: Bool
) async throws {
var configuration = configuration
configuration.isTesting = testing
try await initialize(configuration, app: app)
}

func initializeServer(_ configuration: ParseServerConfiguration,
app: Application) async throws {
func initializeServer(
_ configuration: ParseServerConfiguration,
app: Application
) async throws {

// Parse uses tailored encoders/decoders. These can be retrieved from any ParseObject
ContentConfiguration.global.use(encoder: User.getEncoder(), for: .json)
ContentConfiguration.global.use(decoder: User.getDecoder(), for: .json)

guard let parseServerURL = URL(string: configuration.primaryParseServerURLString) else {
throw ParseError(code: .otherCause,
message: "Could not make a URL from the Parse Server string")
let error = ParseError(
code: .otherCause,
message: "Could not make a URL from the Parse Server string"
)
throw error
}

if !configuration.isTesting {
try setConfiguration(configuration)
do {
// Initialize the Parse-Swift SDK. Add any additional parameters you need
try await ParseSwift.initialize(applicationId: configuration.applicationId,
primaryKey: configuration.primaryKey,
serverURL: parseServerURL,
// POST all queries instead of using GET.
usingPostForQuery: true,
// Do not use cache for anything.
requestCachePolicy: .reloadIgnoringLocalCacheData) { _, completionHandler in
try await ParseSwift.initialize(
applicationId: configuration.applicationId,
primaryKey: configuration.primaryKey,
serverURL: parseServerURL,
// POST all queries instead of using GET.
usingPostForQuery: true,
// Do not use cache for anything.
requestCachePolicy: .reloadIgnoringLocalCacheData
) { _, completionHandler in
// Setup to use default certificate pinning. See Parse-Swift docs for more info
completionHandler(.performDefaultHandling, nil)
}
Expand Down
3 changes: 2 additions & 1 deletion Sources/ParseServerSwift/configure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Vapor
*/
public func parseServerSwiftConfigure(
_ app: Application,
with configuration: ParseServerConfiguration? = nil
with configuration: ParseServerConfiguration? = nil,
using routes: ((Application) throws -> Void)
) async throws {
// Initialize ParseServerSwift
let configuration = try configuration ?? ParseServerConfiguration(app: app)
Expand Down
87 changes: 61 additions & 26 deletions Sources/ParseServerSwift/routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Vapor
import ParseSwift

// swiftlint:disable:next cyclomatic_complexity function_body_length
func routes(_ app: Application) throws {
public func exampleRoutes(_ app: Application) throws {

// A typical route in Vapor.
app.get { req in
Expand All @@ -15,8 +15,10 @@ func routes(_ app: Application) throws {
}

// A simple Parse Hook Function route that returns "Hello World".
app.post("hello",
name: "hello") { req async throws -> ParseHookResponse<String> in
app.post(
"hello",
name: "hello"
) { req async throws -> ParseHookResponse<String> in
// Note that `ParseHookResponse<String>` means a "successful"
// response will return a "String" type.
if let error: ParseHookResponse<String> = checkHeaders(req) {
Expand All @@ -39,8 +41,10 @@ func routes(_ app: Application) throws {
}

// Another simple Parse Hook Function route that returns the version of the server.
app.post("version",
name: "version") { req async throws -> ParseHookResponse<String> in
app.post(
"version",
name: "version"
) { req async throws -> ParseHookResponse<String> in
// Note that `ParseHookResponse<String>` means a "successful"
// response will return a "String" type.
if let error: ParseHookResponse<String> = checkHeaders(req) {
Expand Down Expand Up @@ -89,9 +93,13 @@ func routes(_ app: Application) throws {
}

// A Parse Hook Trigger route.
app.post("score", "save", "before",
object: GameScore.self,
trigger: .beforeSave) { req async throws -> ParseHookResponse<GameScore> in
app.post(
"score",
"save",
"before",
object: GameScore.self,
trigger: .beforeSave
) { req async throws -> ParseHookResponse<GameScore> in
// Note that `ParseHookResponse<GameScore>` means a "successful"
// response will return a "GameScore" type.
if let error: ParseHookResponse<GameScore> = checkHeaders(req) {
Expand All @@ -117,9 +125,13 @@ func routes(_ app: Application) throws {
}

// Another Parse Hook Trigger route.
app.post("score", "find", "before",
object: GameScore.self,
trigger: .beforeFind) { req async throws -> ParseHookResponse<[GameScore]> in
app.post(
"score",
"find",
"before",
object: GameScore.self,
trigger: .beforeFind
) { req async throws -> ParseHookResponse<[GameScore]> in
// Note that `ParseHookResponse<[GameScore]>` means a "successful"
// response will return a "[GameScore]" type.
if let error: ParseHookResponse<[GameScore]> = checkHeaders(req) {
Expand All @@ -144,9 +156,13 @@ func routes(_ app: Application) throws {
}

// Another Parse Hook Trigger route.
app.post("user", "login", "after",
object: User.self,
trigger: .afterLogin) { req async throws -> ParseHookResponse<Bool> in
app.post(
"user",
"login",
"after",
object: User.self,
trigger: .afterLogin
) { req async throws -> ParseHookResponse<Bool> in
// Note that `ParseHookResponse<Bool>` means a "successful"
// response will return a "Bool" type. Bool is the standard response with
// a "true" response meaning everything is okay or continue.
Expand All @@ -161,8 +177,12 @@ func routes(_ app: Application) throws {
}

// A Parse Hook Trigger route for `ParseFile`.
app.on("file", "save", "before",
trigger: .beforeSave) { req async throws -> ParseHookResponse<Bool> in
app.on(
"file",
"save",
"before",
trigger: .beforeSave
) { req async throws -> ParseHookResponse<Bool> in
// Note that `ParseHookResponse<Bool>` means a "successful"
// response will return a "Bool" type. Bool is the standard response with
// a "true" response meaning everything is okay or continue. Sending "false"
Expand All @@ -178,8 +198,12 @@ func routes(_ app: Application) throws {
}

// Another Parse Hook Trigger route for `ParseFile`.
app.post("file", "delete", "before",
trigger: .beforeDelete) { req async throws -> ParseHookResponse<Bool> in
app.post(
"file",
"delete",
"before",
trigger: .beforeDelete
) { req async throws -> ParseHookResponse<Bool> in
// Note that `ParseHookResponse<Bool>` means a "successful"
// response will return a "Bool" type. Bool is the standard response with
// a "true" response meaning everything is okay or continue.
Expand All @@ -194,8 +218,11 @@ func routes(_ app: Application) throws {
}

// A Parse Hook Trigger route for `ParseLiveQuery`.
app.post("connect", "before",
trigger: .beforeConnect) { req async throws -> ParseHookResponse<Bool> in
app.post(
"connect",
"before",
trigger: .beforeConnect
) { req async throws -> ParseHookResponse<Bool> in
// Note that `ParseHookResponse<Bool>` means a "successful"
// response will return a "Bool" type. Bool is the standard response with
// a "true" response meaning everything is okay or continue.
Expand All @@ -210,9 +237,13 @@ func routes(_ app: Application) throws {
}

// Another Parse Hook Trigger route for `ParseLiveQuery`.
app.post("score", "subscribe", "before",
object: GameScore.self,
trigger: .beforeSubscribe) { req async throws -> ParseHookResponse<Bool> in
app.post(
"score",
"subscribe",
"before",
object: GameScore.self,
trigger: .beforeSubscribe
) { req async throws -> ParseHookResponse<Bool> in
// Note that `ParseHookResponse<Bool>` means a "successful"
// response will return a "Bool" type. Bool is the standard response with
// a "true" response meaning everything is okay or continue.
Expand All @@ -227,9 +258,13 @@ func routes(_ app: Application) throws {
}

// Another Parse Hook Trigger route for `ParseLiveQuery`.
app.post("score", "event", "after",
object: GameScore.self,
trigger: .afterEvent) { req async throws -> ParseHookResponse<Bool> in
app.post(
"score",
"event",
"after",
object: GameScore.self,
trigger: .afterEvent
) { req async throws -> ParseHookResponse<Bool> in
// Note that `ParseHookResponse<Bool>` means a "successful"
// response will return a "Bool" type. Bool is the standard response with
// a "true" response meaning everything is okay or continue.
Expand Down
Loading

0 comments on commit 7c11bd3

Please sign in to comment.