How to represent dates consistently between a GraphQL server and client?

I’m struggling to understand how best to represent dates and ensure they can be encoded and decoded consistently between Service and Client when both the service and client and written in Swift.

For context, my server is written using Vapor, Fluent, Graphiti, and GraphQLSwift. My client is using Apollo for iOS.

It’s my understanding that I need to create a custom scalar type when defining the schema which I’ve done using Scalar(Date.self) in my schema definition.

On my server side my models have date fields like @Field(key: "date_purchased") var datePurchased: Date?. The data is stored in the database (Postgres) as a timestamp with timezone field.

When I test the server in a GraphQL playground my date field looks like "datePurchased": 1704407422, which appears to be a double value that seems to be a UNIX timestamp.

On the client side (Apollo) I create a custom schema type:

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
    }
}

Also, I noticed if I used the fluent @Timestamp property wrapper @Timestamp(key: "created_at", on: .create) var dateCreated: Date? and view this in the playground it pulls through as "dateCreated": 1705619227.214435 with decimal places?

What is the best way to reliably manage date formats between client and server when both are using Swift’s Foundation.Date? Is it possible to use other date formats in the external API other than UNIX timestamps?

Hi @cameroncooke

I’m struggling to understand how best to represent dates and ensure they can be encoded and decoded consistently between Service and Client when both the service and client and written in Swift.

What is the best way to reliably manage date formats between client and server when both are using Swift’s Foundation.Date? Is it possible to use other date formats in the external API other than UNIX timestamps?

Since you control both the client and the server you have a bit of flexibility in how you choose to do this and it’s really up to your preference. JSON being the data transport is what you should consider too as it’ll need to go over the wire as JSON String or Number. A number might be the more efficient than strings IMO.

public extension ClientAPI {
    typealias Date = String
}

This doesn’t seem correct if you’re sending a number in the response though.

Thanks, I think I’ve sorted it now, and yes the typealias was wrong which is default from codegen, updated to:

public extension ClientAPI {
    typealias Date = Foundation.Date
}