diff --git a/3.0/docs/styleguide/styleguide.md b/3.0/docs/styleguide/styleguide.md index fdacffe5..738503d0 100644 --- a/3.0/docs/styleguide/styleguide.md +++ b/3.0/docs/styleguide/styleguide.md @@ -125,17 +125,17 @@ The routes.swift file is used to declare route registration for your application ```swift import Vapor -public func routes(_ router: Router) throws { - try router.register(collection: MyControllerHere()) +public func routes(_ router: Router, _ container: Container) throws { + try router.register(collection: MyControllerHere(db: container.connectionPool(to: .mysql))) } ``` You should call this function from `configure.swift` like this: ```swift - services.register(Router.self) { _ -> EngineRouter in + services.register(Router.self) { container -> EngineRouter in let router = EngineRouter.default() - try routes(router) + try routes(router, container) return router } ``` @@ -613,6 +613,47 @@ func update(req: Request, content: User) throws -> Future { } ``` +Controllers should follow the thread-safe architecture when possible. This means passing necessary `Service`s to the controller on initialization instead of making them in the routes. + +**Bad:** + +```swift +final class LoginViewController: RouteCollection { + func boot(router: Router) throws { + router.get("/login", use: login) + } + + func login(req: Request) throws -> String { + let userRepository = try req.make(UserRepository.self) + //do something with it + + return "" + } +} +``` + +**Good:** + +```swift +final class LoginViewController: RouteCollection { + private let userRepository: UserRepository + + init(userRepository: UserRepository) { + self.userRepository = userRepository + } + + func boot(router: Router) throws { + router.get("/login", use: login) + } + + func login(req: Request) throws -> String { + //use `self.userRepository` + + return "" + } +} +``` + Controllers should only cover one idea/feature at a time. If a feature grows to encapsulate a large amount of functionality, routes should be split up into multiple controllers and organized under one common feature folder in the `Controllers` folder. For example, an app that handles generating a lot of analytical/reporting views should break up the logic by specific report to avoid cluttering a generic `ReportsViewController.swift` ## Async