我正在努力理解如何最好地表示日期,并确保当服务和客户端都用 Swift 编写时,它们可以在服务和客户端之间一致地编码和解码。
就上下文而言,我的服务器是使用 Vapor、Fluent、Graphiti 和 GraphQLSwift 编写的。我的客户正在使用 iOS 版 Apollo。
据我所知,在定义模式时需要创建自定义标量类型,我在模式定义中使用
Scalar(Date.self)
完成了该操作。
在我的服务器端,我的模型有像
@Field(key: "date_purchased") var datePurchased: Date?
这样的日期字段。数据作为 timestamp with timezone
字段存储在数据库 (Postgres) 中。
当我在 GraphQL Playground 中测试服务器时,我的日期字段看起来像
"datePurchased": 1704407422,
,它似乎是一个双精度值,似乎是 UNIX 时间戳。
在客户端(Apollo)我创建一个自定义架构类型:
public extension ClientAPI {
typealias Date = String
}
extension Foundation.Date: CustomScalarType {
public init(_jsonValue value: JSONValue) throws {
guard let dateString = value as? String else {
throw JSONDecodingError.couldNotConvert(value: value, to: String.self)
}
guard let date = ISO8601DateFormatter().date(from: dateString) else {
throw JSONDecodingError.couldNotConvert(value: value, to: Date.self)
}
self = date
}
public var _jsonValue: JSONValue {
self.timeIntervalSince1970
}
}
另外,我注意到如果我使用流畅的 @Timestamp 属性包装器
@Timestamp(key: "created_at", on: .create) var dateCreated: Date?
并在操场上查看它,它会显示为带有小数位的 "dateCreated": 1705619227.214435
?
当客户端和服务器都使用 Swift 的 Foundation.Date 时,可靠地管理客户端和服务器之间的日期格式的最佳方法是什么?是否可以在外部 API 中使用除 UNIX 时间戳之外的其他日期格式?
GraphQL Scalars包中的现成
Date
和 DateTime
类型string
的形式交付给客户