Repository: vapor/vapor
File: Sources/Vapor/Routing/RoutingGroups.swift (Swift)

Code before:
    }
    
    /// Returns a group cascading to router with middleware attached
    ///
    ///
    /// **Example:**
    /// ```
    /// let userMustBeAuthorized = UserMustBeAuthorizedMiddleware(....)
    /// let currentUser = CheckIfCurrentUserMiddleware(....)
    ///
    /// // creating new group on router
    /// let users = router.group("user")
    ///   .validate(userMustBeAuthorized)
    ///   .validate(userMustBeCurrentUser)
    ///
    /// // adding "user/profile/" route to router
    /// // both of validations applied
    /// users.get("auth", use: userAuthHandler)
    ///
    /// ```
    ///
    /// [Learn More →](https://docs.vapor.codes/3.0/vapor/route-group/#path-components)
    ///
    /// - Parameter middleware: Middleware
    /// - Returns: RouterGroup with middleware attached
    public func validate(_ middleware: Middleware...) -> RouteGroup {
        return RouteGroup(cascadingTo: self, middleware: middleware)
    }
    
    /// Returns a group cascading to router with validator attached
    ///
    ///
    /// **Example:**
    /// ```
    /// let userMustBeAuthorized = { req, next in
    ///     return try userService.authorized(user)
    /// }
    ///
    /// let currentUser  = { req, next in
    ///     return try userService.isCurrentUser(req)
    /// }
    ///
    /// // creating new group on router
    /// let users = router.group("user")
    ///   .validate(userMustBeAuthorized)
    ///   .validate(userMustBeCurrentUser)
    ///
    /// // adding "user/profile/" route to router
    /// // both of validations applied
    /// users.get("auth", use: userAuthHandler)
    ///

Review comment (suggestion):
I love this PR! ❤️ 

I think we. should change the name of this `validate` function, because a middleware may not do validation. It can do file serving, too, for example

Code after:
    }
}

extension Router {
    // MARK: - Create new group
    
    /// Creates a group cascading to router or group with the provided path components
    ///
    ///
    /// **Example:**
    /// ```
    /// // creating new group on router
    /// let users = router.grouped("user")
    ///
    /// // adding "user/auth/" route to router
    /// users.get("auth", use: userAuthHandler)
    ///
    /// // adding "user/profile/" route to router
    /// users.get("profile", use: userProfileHandler)
    ///
    /// ```
    ///
    /// [Learn More →](https://docs.vapor.codes/3.0/vapor/route-group/#path-components)
    ///
    /// - Parameter path: Group path components separated by commas
    /// - Returns: created RouteGroup
    public func grouped(_ path: PathComponent...) -> RouteGroup {
        return RouteGroup(cascadingTo: self, components: path)
    }
    
    
    /// Creates a group cascading to router or group with the provided path components
    /// and use `configure` closure to configure crated group
    ///
    /// **Example:**
    /// ```
    /// // create new group and adds on router
    /// router.group(with: "user") { group in
    ///     // adding "user/auth/" route to router
    ///     group.get("auth", use: userAuthHandler)
    ///
    ///     // adding "user/profile/" route to router
    ///     group.get("profile", use: userProfileHandler)
    /// }
    ///
    /// ```
    ///
    /// [Learn More →](https://docs.vapor.codes/3.0/vapor/route-group/#path-components)
    ///
    /// - Parameter path: Group path components separated by commas
    /// - Returns: created RouteGroup