-
-
Save adirburke/855b8a9729002c8f45b756e091a5a224 to your computer and use it in GitHub Desktop.
Using SwiftProtobuf with Vapor 4
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 ByteBuffer { | |
public func allData() -> Data { | |
return getData(at: 0, length: readableBytes) ?? Data() | |
} | |
} | |
extension Request { | |
public func decodeMessage<M: SwiftProtobuf.Message>(_ type: M.Type = M.self) throws -> M { | |
let data = self.body.data?.allData() ?? Data() | |
if headers.contentType == .json { | |
return try M(jsonUTF8Data: data) | |
} | |
return try M(serializedData: data) | |
} | |
} | |
extension SwiftProtobuf.Message { | |
fileprivate func toHTTPResponse(json: Bool = false) throws -> Response { | |
let http = Response(status: .ok) | |
if json { | |
http.headers.contentType = .json | |
http.body = .init(string: try jsonString()) | |
} else { | |
http.headers.contentType = .init(type: "application", subType: "protobuf") | |
http.body = .init(data: try serializedData()) | |
} | |
return http | |
} | |
public func toResponse(on req: Request) throws -> Response { | |
let json = req.headers.accept.contains(where: { $0.mediaType == .json }) | |
let response = try toHTTPResponse(json: json) | |
return response | |
} | |
} | |
extension EventLoopFuture { | |
public func toResponse<M>(_ type: M.Type = M.self, on req: Request) -> EventLoopFuture<Response> where Value : SwiftProtobuf.Message { | |
return self.flatMapThrowing { 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