Group Group Group Group Group Group Group Group Group

Return parent and merge data

Hi again,
I am struggling a lot with lots of new concepts with Futures / Swift / Vapor… and I think I just need some help to get me moving again…
I’ve based the code on the Acronym / User example in the book and build the parent / child relationship where EventType is the parent.

I created some handlers for returning some event data and I set up a handler to return the parent EventType… all working OK.

func getEventTypeHandler(_ req: Request) throws -> Future<EventType> {
    return try req
        .parameters.next(Event.self)
        .flatMap(to: EventType.self) { event in
            event.eventType.get(on: req)
    }
}

func getAllHandler(_ req: Request) throws -> Future<[Event]> {
    return Event
        .query(on: req)
        .all()
}

func getHandler(_ req: Request) throws -> Future<Event> {
    return try req.parameters.next(Event.self)
}

What I need to do is add a new handler that merges the data sets and returns both the Event and the single EventType parent data in one query…

So what I am thinking is duplicating the getHandler and adding the extra capability… but this is as far as I’ve gotten. I’ve added comments for demonstrating my thinking here…

func getExtendedHandler(_ req: Request) throws -> Future {
let event = try req.parameters.next(Event.self)
// let eventType = try getEventTypeHandler(Event.self)
// somehow merge event and eventType - there are no conflicting properties except .id
// in a separate bit of thinking - I’ll need to perhaps manipulate the JSON before I return it… I’d love to see an example of that too.
//
return event
}

I need to nail this because I’ve got a bunch of functions that need to pull data from the database and then potentially parse and change the results before returning the final JSON.

any help appreciated

@0xtim Can you please help with this when you get a chance? Thank you - much appreciated! :]

So is what I came up with… Not sure if it’s ideal… looking for some advice

func getExtendedEventHandler(_ req: Request) throws -> Future {

    let extendedEvent = try req.parameters.next(Event.self)
        .flatMap(to: ExtendedEvent.self) { event in
            let futureA = Event.find(event.id!, on: req)
            let futureB = EventType.find(event.eventTypeID, on: req)
            return map(to: ExtendedEvent.self, futureA, futureB) { event, eventType in
                return ExtendedEvent(event: event!, eventType: eventType!)
            }
        }
    return extendedEvent
}

final class ExtendedEvent: Codable {
    var event: Event
    var eventType: EventType
    init(event: Event, eventType: EventType) {
        self.event = event
        self.eventType = eventType
    }
}
extension ExtendedEvent: Content { }

The code actually looks pretty good (though you should handle the optionals). The latest release of the book contains an advanced Fluent chapter that should help with this as well!