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?
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 }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With