Search code examples
jsonswiftdecodevapor

How to decode body (ByteBuffer) to Content in Vapor 4?


I can easily decode response.content as it's described in Vapor docs, when ResponseReceipt conforms to Content protocol here.

let receipt = try? response.content.decode(ResponseReceipt.self)

But it's not that easy to understand how to decode response.body using Vapor's tools as it's ByteBuffer. How can I decode response.body in the similar native to Vapor manner?


Solution

  • First of all it is important to understand that ByteBuffer is kinda collection of bytes, so you could just read bytes from it and try to initialize Data like this

    guard let byteBuffer = req.body.data else { throw Abort(.badRequest) }
    let data = Data(buffer: byteBuffer)
    let receipt = try JSONDecoder().decode(ResponseReceipt.self, from: data)
    

    or like this

    guard let byteBuffer = response.body.data else { throw Abort(.badRequest) }
    guard let data = byteBuffer.getData(at: 0, length: byteBuffer.readableBytes) else { throw Abort(.badRequest) }
    let receipt = try JSONDecoder().decode(ResponseReceipt.self, from: data)
    

    But with Vapor you have two more convenient ways to decode byte buffer

    Choose which one you like more

    guard let byteBuffer = response.body.data else { throw Abort(.badRequest) }
    let receipt = try JSONDecoder().decode(ResponseReceipt.self, from: byteBuffer)
    

    one more

    guard let byteBuffer = response.body.data else { throw Abort(.badRequest) }
    guard let receipt = try byteBuffer.getJSONDecodable(ResponseReceipt.self, at: 0, length: byteBuffer.readableBytes)
    

    and one more

    guard let byteBuffer = response.body.data else { throw Abort(.badRequest) }
    guard let receipt = try byteBuffer.getJSONDecodable(ResponseReceipt.self, decoder: JSONDecoder(), at: 0, length: byteBuffer.readableBytes)