Vapor 3 GET route for sensitive data

Viewed 112

Using numerous tutorials on Vapor 3 I've failed to figure out how I can edit output JSON, f.e. to get particular User object I create route:

protectedRouter.get("users", User.parameter, use: userController.user)

And method in UserController:

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

And it, of course, sends everything that inside the User object, including email and hashed password. Great. How can I avoid this? I mean I want to send only public information about the user (name, nick, id etc...).

1 Answers

Create a separate struct representing your desired output structure. Conform that struct to Content. Whenever you return your User, convert it to that struct first. Adding an extension to User that does this is nice for convenience.

A common pattern emerging is to nest this struct inside the Model calling it Public. i.e.,

extension User {
    struct Public: Content { ... }

    func makePublic() -> Public { ... }
}

Your routes would then return User.Public instead of User. Note that this pattern is also useful in reverse, for creating a separate "input" representation for your User.

You can read more about this in Vapor's docs at Vapor → Content → Dynamic Properties.

Related