为什么我们有Node?(Why do we have Node?)
web是非常严格的,Swift是非常类型安全的,这是在Swift进行Web开发时的主要问题。Node是我们试图为这个问题提供解决方案。
什么是节点?(What is Node?)
节点是一种数据抽象,重点是在不同类型之间建立中介。例如,来自客户端的json可能会使用节点在JSON和本身之间进行转换。
如何使用它?(How do I use it?)
如果您熟悉不那么类型安全的语言,那么Node可能会有一点不同,让我们看看几个例子,以及我们如何开始在我们的项目中使用Node。最常见的情况是,我们将使用节点转换。
NodeInitializable
NodeInitializable可以被读取和理解为An object that can be initialized with a Node
。我们来看一个简单的实现。
struct Person: NodeInitializable {
let name: String
let age: Int
init(node: Node) throws {
name = try node.get("name")
age = try node.get("age")
}
}
现在我们有了这个,我们就可以轻松地将抽象数据转换成一个Person。以下是可能的样子:
let person = try Person(node: json)
注意:对于JSON和数据库行类型,有一些更高级的功能选项,我们稍后会介绍。
通过让我们的Person
对象继承NodeInitializable
,我们还可以使用更高级的方法,如数组:
let people = try [Person](node: jsonArray)
NodeRepresentable
NodeRepresentable可以被读取和理解为An object that can be represented as a Node
。我们来看看一个简单的实现。我们将继续使用上面的Person
示例
extension Person: NodeRepresentable {
func makeNode(in context: Context) throws -> Node {
var node = Node(context)
try node.set("name", name)
try node.set("age", age)
return node
}
}
现在我们已经做到了这一点,我们可以轻松地将我们person
或一组Person
对象转换成一个Node
。
let node = try person.makeNode(in: nil)
并且还用于集合,如数组
let node = try [kim, joe, jan].makeNode(in: nil)
环境(Context)
到目前为止,我们已经看到很多Context
,但是它是为了什么。当我们序列化或映射对象时,我们可能会有很多不同的情况,我们以不同的方式进行映射。也许一个是数据库,一个是视图,一个是JSON等。
如果您使用Vapor,我们提供了大量的环境和更多的本地集成选项,但是这里可以定义自己的内容。
import Node
final class MyContext: Context {
}
let myContext = MyContext()
extension Context {
var isMyContext: Bool {
return self is MyContext
}
}
现在我们的对象中,我们可以添加特殊的行为。
extension Person: NodeRepresentable {
func makeNode(in context: Context) throws -> Node {
var node = Node(context)
try node.set("name", name)
try node.set("age", age)
if context.isMyContext {
try node.set("special-attribute", special)
}
return node
}
}
我们可以这样调用:
let specialNode = person.makeNode(in: myContext)
这是一个常见的用法,但可以适应任何需要特殊元数据的场景,以帮助我们正确序列化或映射我们的对象。
NodeConvertible
NodeConvertible只是可代表和可初始化的组合。这些对象可以轻松地转换到Node。从我们以前的Person对象中我们应该能够做到这一点:
// ..
let node = person.makeNode(in: myContext)
let back = try Person(node: node)
print("\(person) went to node and back to \(back)")