跳转至

Routing

路由是用来管理控制 HTTP 请求入口的。

先看下 App 目录下的 routes.swift 文件,代码如下。

func routes(_ app: Application) throws {
    app.get { req in
        return "It works!"
    }

    app.get("hello") { req -> String in
        return "Hello, world!"
    }

    ......
}

通过 appApplication 类实例)可以对路由进行相关的配置。

监听指定路径

app.get("hello") { req -> String in
    return "Hello, world!"
}

如上代码的作用是,监听了 "hello" 路径,当客户端发起 /hello 为路径的 GET 请求时,将会触发该回调方法的执行,最终返回 "Hello, world!" 给客户端展现。

测试 hello

  • Request
curl -X GET http://localhost:8080/hello
  • Response
Hello, world!

同理,POSTPUTDELETE 等操作行为也是类似的。

示例如下

// Method: POST, Path: test1
app.post("test1") { req in
    return "Method: POST, Path: test1"
}

// Method: PUT, Path: test2
app.put("test2") { req in
    return "Method: PUT, Path: test2"
}

// Method: DELETE, Path: test3
app.delete("test3") { req in
    return "Method: DELETE, Path: test3"
}

监听指定路径集合

有时候定义的路径都是在某一个特定路径名下的(比如 v1),这时候就需要路由组来进行管理了。

// 路由组
app.group("v1") { builder in

    // 此处定义的所有请求路径都是在路由组("v1")下面的。
    builder.get("name") { req in
        return "Handle path: v1/name"
    }

    builder.get("avatar") { req in
        return "Handle path: v1/avatar"
    }
}

nameavatar 都是挂在 v1 后面,相当于 v1/namev1/avatar

测试 v1/name

  • Request
curl -X GET http://localhost:8080/v1/name
  • Response
Handle path: v1/name

测试 v1/avatar

  • Request
curl -X GET http://localhost:8080/v1/avatar
  • Response
Handle path: v1/avatar

带参数的路由

有时候请求的接口需要在 URL 上携带参数,比如 /user/1,可通过 :<参数名> 格式来定义该参数,并通过 req.parameters.get(<参数名>) 来获取传递过来的参数,代码如下。

app.get("user", ":userId") { req -> String in
    let userId = req.parameters.get("userId")
    return "userId = \(userId ?? "")"
}

测试 /user/1

  • Request
curl --location --request GET 'http://localhost:8080/user/1'
  • Response
userId = 1

如果希望接收 /user?id=1 这样格式的参数的话,可通过 req.query["id"] 来获取到对应的 id 参数,代码如下。

app.get("user") { req -> String in
    let userId: String? = req.query["id"]
    return "userId = \(userId ?? "")"
}

测试 /user?id=2

  • Request
curl --location --request GET 'http://localhost:8080/user?id=2'
  • Response
userId = 2

另外,POST 请求参数往往是存放在 httpbody 中的,可通过 req.content.decode 方法解析传递过来的 body 数据,代码如下。

func createUser(req: Request) throws -> UserInput {
    let userInput = try req.content.decode(UserInput.self)

    return userInput
}

其中,UserInput 定义如下

struct UserInput: Content {
    var id: Int?
    var username: String
}

测试 body 解析

  • Request
curl --location --request POST 'http://127.0.0.1:8080/test' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "SwiftMic1"
}'
  • Response
{"username":"SwiftMic1"}