Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vapor 3 API: embed Future<Model> in response object

Tags:

swift

vapor

Suppose I have a model called Estimate. I have a Vapor 3 API that I want to return a list of these models, filtered by query parameters. Doing so currently returns a Future<[Estimate]>, which results in the API returning JSON that looks like this:

[{estimate object}, {estimate object}, ...]

Instead, I'd like make it return something this:

{"estimates": [{estimate object}, {estimate object}, ...]}

So, the same thing as before, but wrapped in a JSON object with a single key, "estimates".

According to the documentation, any time I want to return something non-default, I should make a new type for it; this suggests to me I should create a type like:

final class EstimatesResponse: Codable {
  var estimates: [Estimate]?
}

However, after filtering I get a Future<[Estimate]> and NOT a pure [Estimate] array, meaning that I couldn't assign it to my EstimatesResponse estimates property. It seems weird to make the type of estimates be Future<[Estimate]>, and I'm not sure how that'd turn out.

How, then, can I return JSON of the correct format?

like image 415
Elliot Schrock Avatar asked Apr 08 '26 19:04

Elliot Schrock


1 Answers

First, you need to create Codable object, I prefer struct as below. Must implement protocol Content for routing.

struct EstimatesResponse: Codable {
  var estimates: [Estimate]
 }

 extension EstimatesResponse: Content { } 

I assumed that you are using a controller and inside the controller, you can use the following pseudo-code. Adjust your code so that val is Future<[Estimate]>, then use flatmap/map to get [Estimate].

func  getEstimates(_ req: Request) throws -> Future<EstimatesResponse> {
        let val = Estimate.query(on: req).all()
        return val.flatMap { model in
            let all = EstimatesResponse(estimates: model)
            return Future.map(on: req) {return all }
        }
    }
like image 64
Razib Mollick Avatar answered Apr 12 '26 16:04

Razib Mollick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!