Vapor 3 RC 2 is out! To update, ensure that your Package.swift contains something like:
.package(url: "https://github.com/vapor/vapor.git", from: "3.0.0-rc"),
.package(url: "https://github.com/vapor/fluent-mysql.git", from: "3.0.0-rc"),
.package(url: "https://github.com/vapor/leaf.git", from: "3.0.0-rc"),Depending on your dependenices - make sure that you use the "X.X.X-rc" - that's the important bit.
You will also need to update your toolbox - Vapor 3 RC2 now requires LibreSSL for macOS with NIO - you can either upgrade you toolbox (brew upgrade vapor) or just install LibreSSL (brew install libressl)
The await(on:) function has now been deprecated, and was always a stopgap. To accept data before learning about Futures you can use the POST helper function:
router.post(InfoData.self, at: "info") { req, data -> InfoResponse in
return InfoResponse(request: data)
}As above, use the new function for your POST route:
router.post(UserInfoData.self, at: "user-info") { req, userInfo -> String in
return "Hello \(userInfo.name), you are \(userInfo.age)!"
}Remove the await(on:) call in AcronymsController.swift. You can now call save(on:) directly on a Future<Model>:
func createHandler(_ req: Request) throws -> Future<Acronym> {
let acronym = try req.content.decode(Acronym.self)
return acronym.save(on: req)
}As for Video 3, in CategoriesController.swift you should now have:
func createHandler(_ req: Request) throws -> Future<Category> {
let category = try req.content.decode(Category.self)
return category.save(on: req)
}Fluent's get(on:) query now throws so the getCreatorHandler(_:) in AcronymsController.swift now looks like:
func getCreatorHandler(_ req: Request) throws -> Future<User> {
return try req.parameter(Acronym.self).flatMap(to: User.self) { acronym in
return try acronym.creator.get(on: req)
}Fluent's group(_:) and filter(_:) queries throw so the searchHandler(_:) in AcronymsController.swift now looks like:
func searchHandler(_ req: Request) throws -> Future<[Acronym]> {
guard let searchTerm = req.query[String.self, at: "term"] else {
throw Abort(.badRequest)
}
return try Acronym.query(on: req).group(.or) { or in
try or.filter(\.short == searchTerm)
try or.filter(\.long == searchTerm)
}.all()
}The configuration for MySQLDatabase is now provided in a separate type. In configure.swift it should now look like:
var databases = DatabaseConfig()
let mysqlConfig = MySQLDatabaseConfig(hostname: "localhost", port: 3306, username: "til", password: "password", database: "vapor")
let database = MySQLDatabase(config: mysqlConfig)
databases.add(database: database, as: .mysql)
services.register(databases)As Fluent's get(on:) query now throws, the acronymHandler(_:) now looks like:
func acronymHandler(_ req: Request) throws -> Future<View> {
return try req.parameter(Acronym.self).flatMap(to: View.self) { acronym in
return try acronym.creator.get(on: req).flatMap(to: View.self) { creator in
let context = AcronymContext(title: acronym.long, acronym: acronym, creator: creator)
return try req.leaf().render("acronym", context)
}
}
}Crypto's Random functions have been tweaked. The Token extension to generate a token should now look like:
extension Token {
static func generate(for user: User) throws -> Token {
let random = try CryptoRandom().generateData(count: 16)
return try Token(token: random.base64EncodedString(), userID: user.requireID())
}
}BCrypt functions have been renamed as well. In your UsersController you'll need to import Crypto and change your createHandler(_:) should look like:
func createHandler(_ req: Request) throws -> Future<User> {
return try req.content.decode(User.self).flatMap(to: User.self) { user in
let hasher = try req.make(BCryptDigest.self)
user.password = try String.convertFromData(hasher.hash(user.password))
return user.save(on: req)
}
}When creating the basicAuthMiddleware you need to rename the Verifier. Your line should look like:
let basicAuthMiddleware = User.basicAuthMiddleware(using: BCryptDigest())When creating the verifier BCrypt types have been renamed:
let verifier = try req.make(BCryptDigest.self)
Hello *,
Just a few comments to keep in mind when working with more recent versions of Vapor and some of the other components such as Crypto and Leaf.
Notes:
import Cryptowhen using BCryptDigest()req.parameters.next()is used.Abort()function at AcronymsController.swift:public func hash(_ plaintext: LosslessDataConvertible, cost: Int = 12, salt: LosslessDataConvertible? = nil) throws -> String {...so there is no need to use
String.convertFromData()the resulting function at UsersController.swift would look like:DatabaseConfig()has been renamed toDatabasesConfig()I hope you all find these comments useful.
Thank you very much