美文网首页
Vapor文档学习七:Controllers

Vapor文档学习七:Controllers

作者: Supremodeamor | 来源:发表于2017-04-19 15:53 被阅读101次

    Controllers可以帮你将相关功能整合到一起,或者创建一些依赖性的资源。

    Basic

    下面是一个基本的Controller

    final class HelloController {
        func sayHello(_ req: Request) throws -> ResponseRepresentable {
            guard let name = req.data["name"] else { 
                throw Abort.badRequest 
            }
            return "Hello, \(name)"
        }
    }
    

    一个简单的控制器类不需要遵守任何协议,你可以自由的设计、实现你想要的功能。

    Registering

    实现注册唯一要做的事情就是为controller中的每个方法进行签名(看看上面sayHello方法的结构)。为了将controller中的方法注册到路由中去,需要方法实现类似于(Request) throws -> ResponseRepresentable的结构。 RequestResponseRepresentable的使用需要引入HTTP模块。

    let hc = HelloController()
    drop.get("hello", handler: hc.sayHello)
    

    由于sayHello方法的签名与drop.get方法的闭包签名相匹配,所以我们可以直接传递。

    Type Safe(类型安全)

    你也可以使用具有类型安全路由的控制器方法:

    final class HelloController {
        ...
    
        func sayHelloAlternate(_ req: Request, _ name: String) -> ResponseRepresentable {
            return "Hello, \(name)"
        }
    }
    

    sayHelloAlternate方法添加到HelloController当中,它可以接收第二个参数name: String

    let hc = HelloController()
    drop.get("hello", String.self, handler: hc.sayHelloAlternate)
    

    类型安全的drop.get接收(Request, String) throws -> ResponseRepresentable签名之后,我们的方法就可以用作这个路由的闭包。

    Resources

    遵守ResourceRepresentable的Controllers可以很轻松的作为RESTful资源注册到路由当中,下面用UserController举例:

    final class UserController {
        func index(_ request: Request) throws -> ResponseRepresentable {
            return try User.all().makeNode().converted(to: JSON.self)
        }
    
        func show(_ request: Request, _ user: User) -> ResponseRepresentable {
            return user
        }
    }
    

    上面的UserController是一个很基本的controller,包含indexshow两个路由,index路由返回的是所有user列表的json数据,show路由返回的是一个具体user的json数据。
    我们注册这个controller的时候这样写:

    let users = UserController()
    drop.get("users", handler: users.index)
    drop.get("users", User.self, handler: users.show)
    

    但是ResourceRepresentable协议使得这个标准的RESTful结构变得非常容易:

    extension UserController: ResourceRepresentable {
        func makeResource() -> Resource<User> {
            return Resource(
                index: index,
                show: show
            )
        }
    }
    

    UserController遵守ResourceRepresentable协议要求将
    showindex方法的签名与Resource<User>期望的格式相匹配。

    看一下Resource类的实现:

    final class Resource<Model: StringInitializable> {
        typealias Multiple = (Request) throws -> ResponseRepresentable
        typealias Item = (Request, Model) throws -> ResponseRepresentable
    
        var index: Multiple?
        var store: Multiple?
        var show: Item?
        var replace: Item?
        var modify: Item?
        var destroy: Item?
        var clear: Multiple?
        var aboutItem: Item?
        var aboutMultiple: Multiple?
    
        ...
    }
    

    现在UserController遵守了ResourceRepresentable协议,注册路由就变的简单了:

    let users = UserController()
    drop.resource("users", users)
    

    drop.resource只会注册通过调用makeResource()方法提供的路由。在这种情况下,只会启用indexshow这两个路由。

    Note:drop.resource还为OPTIONS requests添加了有用的默认值。这些可以被重写。

    Folder

    Controllers可以放在应用的任何目录下,但是一般放在Controllers/目录中。

    Modules

    如果你的项目比较庞大,你可能需要在单独的模块中创建Controllers,这样可以允许你对你的controllers进行单元测试。更多关于模块创建的信息请参考文档Swift Package Manager

    相关文章

      网友评论

          本文标题:Vapor文档学习七:Controllers

          本文链接:https://www.haomeiwen.com/subject/gaxhzttx.html