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!"
}
......
}
通过 app(Application 类实例)可以对路由进行相关的配置。
监听指定路径¶
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!
同理,POST、PUT、DELETE 等操作行为也是类似的。
示例如下
// 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"
}
}
name 和 avatar 都是挂在 v1 后面,相当于 v1/name 和 v1/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 请求参数往往是存放在 http 的 body 中的,可通过 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"}