From b5f82efbac26c7fd3cee2a5cd2abb2654da4a5e3 Mon Sep 17 00:00:00 2001 From: maximkrouk Date: Fri, 15 Apr 2022 05:04:43 +0400 Subject: [PATCH] Add custom encoders support for router --- Package.resolved | 205 ----------------------- README.md | 6 +- Sources/GraphQLKit/Graphiti+Router.swift | 83 +++++++-- 3 files changed, 78 insertions(+), 216 deletions(-) delete mode 100644 Package.resolved diff --git a/Package.resolved b/Package.resolved deleted file mode 100644 index c8f7acc..0000000 --- a/Package.resolved +++ /dev/null @@ -1,205 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "async-http-client", - "repositoryURL": "https://github.com/swift-server/async-http-client.git", - "state": { - "branch": null, - "revision": "8fa7f082b155ea325bcf7b2dbffaf81d4eea1ae4", - "version": "1.5.1" - } - }, - { - "package": "async-kit", - "repositoryURL": "https://github.com/vapor/async-kit.git", - "state": { - "branch": null, - "revision": "2a198346c4403d6c120a5fe43b70101800c878ff", - "version": "1.6.0" - } - }, - { - "package": "console-kit", - "repositoryURL": "https://github.com/vapor/console-kit.git", - "state": { - "branch": null, - "revision": "75ea3b627d88221440b878e5dfccc73fd06842ed", - "version": "4.2.7" - } - }, - { - "package": "fluent", - "repositoryURL": "https://github.com/vapor/fluent.git", - "state": { - "branch": null, - "revision": "5810a409eb0271a576f68887fa6713dae3985056", - "version": "4.3.1" - } - }, - { - "package": "fluent-kit", - "repositoryURL": "https://github.com/vapor/fluent-kit.git", - "state": { - "branch": null, - "revision": "7d9982a788dc0bbc80937537a0e2b0a42d282202", - "version": "1.15.1" - } - }, - { - "package": "Graphiti", - "repositoryURL": "https://github.com/GraphQLSwift/Graphiti.git", - "state": { - "branch": null, - "revision": "af903a243862c6427935677b91f67df0c21f2a71", - "version": "0.26.0" - } - }, - { - "package": "GraphQL", - "repositoryURL": "https://github.com/GraphQLSwift/GraphQL.git", - "state": { - "branch": null, - "revision": "e5de315125f8220334ba3799bbd78c7c1ed529f7", - "version": "2.0.0" - } - }, - { - "package": "multipart-kit", - "repositoryURL": "https://github.com/vapor/multipart-kit.git", - "state": { - "branch": null, - "revision": "c9ea04017b7fb3b1f034ad7a77f8e53d3e080be5", - "version": "4.2.1" - } - }, - { - "package": "routing-kit", - "repositoryURL": "https://github.com/vapor/routing-kit.git", - "state": { - "branch": null, - "revision": "a0801a36a6ad501d5ad6285cbcd4774de6b0a734", - "version": "4.3.0" - } - }, - { - "package": "sql-kit", - "repositoryURL": "https://github.com/vapor/sql-kit.git", - "state": { - "branch": null, - "revision": "b70d1fea1b544dd819c17e83d59fb9aa85c81e74", - "version": "3.10.0" - } - }, - { - "package": "swift-backtrace", - "repositoryURL": "https://github.com/swift-server/swift-backtrace.git", - "state": { - "branch": null, - "revision": "d3e04a9d4b3833363fb6192065b763310b156d54", - "version": "1.3.1" - } - }, - { - "package": "swift-collections", - "repositoryURL": "https://github.com/apple/swift-collections", - "state": { - "branch": null, - "revision": "9d8719c8bebdc79740b6969c912ac706eb721d7a", - "version": "0.0.7" - } - }, - { - "package": "swift-crypto", - "repositoryURL": "https://github.com/apple/swift-crypto.git", - "state": { - "branch": null, - "revision": "3bea268b223651c4ab7b7b9ad62ef9b2d4143eb6", - "version": "1.1.6" - } - }, - { - "package": "swift-log", - "repositoryURL": "https://github.com/apple/swift-log.git", - "state": { - "branch": null, - "revision": "5d66f7ba25daf4f94100e7022febf3c75e37a6c7", - "version": "1.4.2" - } - }, - { - "package": "swift-metrics", - "repositoryURL": "https://github.com/apple/swift-metrics.git", - "state": { - "branch": null, - "revision": "3edd2f57afc4e68e23c3e4956bc8b65ca6b5b2ff", - "version": "2.2.0" - } - }, - { - "package": "swift-nio", - "repositoryURL": "https://github.com/apple/swift-nio.git", - "state": { - "branch": null, - "revision": "f2705f9655ede35399b12040e892cf653126de98", - "version": "2.32.2" - } - }, - { - "package": "swift-nio-extras", - "repositoryURL": "https://github.com/apple/swift-nio-extras.git", - "state": { - "branch": null, - "revision": "f72c4688f89c28502105509186eadc49a49cb922", - "version": "1.10.0" - } - }, - { - "package": "swift-nio-http2", - "repositoryURL": "https://github.com/apple/swift-nio-http2.git", - "state": { - "branch": null, - "revision": "42bdcae4ac4913507a5ee7af963c559deb60d1fc", - "version": "1.18.2" - } - }, - { - "package": "swift-nio-ssl", - "repositoryURL": "https://github.com/apple/swift-nio-ssl.git", - "state": { - "branch": null, - "revision": "2e74773972bd6254c41ceeda827f229bccbf1c0f", - "version": "2.15.0" - } - }, - { - "package": "swift-nio-transport-services", - "repositoryURL": "https://github.com/apple/swift-nio-transport-services.git", - "state": { - "branch": null, - "revision": "9571a61d236c5253b6a255a2d13fac536a1e2625", - "version": "1.11.2" - } - }, - { - "package": "vapor", - "repositoryURL": "https://github.com/vapor/vapor.git", - "state": { - "branch": null, - "revision": "a8bd13fa10b14d2c014f002a4eed0558f66bcf6f", - "version": "4.48.5" - } - }, - { - "package": "websocket-kit", - "repositoryURL": "https://github.com/vapor/websocket-kit.git", - "state": { - "branch": null, - "revision": "b1c4df8f6c848c2e977726903bbe6578eed723ad", - "version": "2.2.0" - } - } - ] - }, - "version": 1 -} diff --git a/README.md b/README.md index afedeb3..702e99d 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,11 @@ In your `configure.swift` file call the `register(graphQLSchema: Schema(graphQLSchema schema: Schema, withResolver rootAPI: RootType, at path: PathComponent="graphql", postBodyStreamStrategy: HTTPBodyStreamStrategy = .collect) { + public func register( + graphQLSchema schema: Schema, + withResolver rootAPI: RootType, + at path: PathComponent="graphql", + postBodyStreamStrategy: HTTPBodyStreamStrategy = .collect, + customEncoder: ContentEncoder? = nil + ) { self.on(.POST, path, body: postBodyStreamStrategy) { (request) -> EventLoopFuture in - try request.resolveByBody(graphQLSchema: schema, with: rootAPI) - .flatMap({ - $0.encodeResponse(status: .ok, for: request) - }) + try request.resolveByBody( + graphQLSchema: schema, + with: rootAPI + ).flatMap { result in + result.encodeResponse( + status: .ok, + for: request, + using: customEncoder + ) + } } self.get(path) { (request) -> EventLoopFuture in - try request.resolveByQueryParameters(graphQLSchema: schema, with: rootAPI) - .flatMap({ - $0.encodeResponse(status: .ok, for: request) - }) + try request.resolveByQueryParameters( + graphQLSchema: schema, + with: rootAPI + ).flatMap { result in + result.encodeResponse( + status: .ok, + for: request, + using: customEncoder + ) + } } } } @@ -23,4 +41,49 @@ enum GraphQLResolveError: Swift.Error { case noQueryFound } -extension GraphQLResult: Content { } +extension GraphQLResult: Content { + func encodeResponse( + status: HTTPStatus, + headers: HTTPHeaders = [:], + for request: Request, + using encoder: ContentEncoder? + ) -> EventLoopFuture { + if let encoder = encoder { + let response = Response() + do { + var body = ByteBufferAllocator().buffer(capacity: 0) + try encoder.encode(self, to: &body, headers: &response.headers) + response.body = Response.Body(buffer: body) + + for (name, value) in headers { + response.headers.replaceOrAdd( + name: name, + value: value + ) + } + + response.status = status + } catch { + return request.eventLoop.makeFailedFuture(error) + } + return request.eventLoop.makeSucceededFuture(response) + } else { + return self.encodeResponse( + status: status, + headers: headers, + for: request + ) + } + } +} + +extension GraphQLJSONEncoder: ContentEncoder { + public func encode( + _ encodable: E, + to body: inout ByteBuffer, + headers: inout HTTPHeaders + ) throws where E: Encodable { + headers.contentType = .json + try body.writeBytes(self.encode(encodable)) + } +}