Created
March 3, 2019 11:19
-
-
Save vzsg/7a309d24a1a92cf706a0dd17183673b9 to your computer and use it in GitHub Desktop.
Using SwiftProtobuf with Vapor 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vapor | |
import SwiftProtobuf | |
import Foundation | |
extension Request { | |
public func decodeMessage<M: SwiftProtobuf.Message>(_ type: M.Type = M.self) throws -> M { | |
let data = http.body.data ?? Data() | |
if http.contentType == MediaType.json { | |
return try M(jsonUTF8Data: data) | |
} | |
return try M(serializedData: data) | |
} | |
} | |
extension SwiftProtobuf.Message { | |
fileprivate func toHTTPResponse(json: Bool = false) throws -> HTTPResponse { | |
var http = HTTPResponse(status: .ok) | |
if json { | |
http.contentType = MediaType.json | |
http.body = try jsonUTF8Data().convertToHTTPBody() | |
} else { | |
http.contentType = MediaType(type: "application", subType: "x-protobuf") | |
http.body = try serializedData().convertToHTTPBody() | |
} | |
return http | |
} | |
public func toResponse(on req: Request) throws -> Response { | |
let json = req.http.accept.contains(where: { $0.mediaType == MediaType.json }) | |
return Response(http: try toHTTPResponse(json: json), using: req) | |
} | |
} | |
extension Future { | |
public func toResponse<M>(_ type: M.Type = M.self, on req: Request) -> Future<Response> where Expectation: SwiftProtobuf.Message { | |
return map { try $0.toResponse(on: req) } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
router.get("test") { req -> Response in | |
var profile = Proto_UserProfile() | |
var user = Proto_User() | |
user.nickname = "FooBar" | |
user.firstName = "Foo" | |
user.lastName = "Bar" | |
profile.user = user | |
return try profile.toResponse(on: req) | |
} | |
// Calling without an accept header: curl localhost:8080/test | |
// --> returns binary message | |
// Calling with accept header: curl localhost:8080/test -H "Accept: application/json" | |
// --> returns JSON | |
// {"user":{"nickname":"FooBar","firstName":"Foo","lastName":"Bar"}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for sharing! It is clever!