vapor/vapor

Cannot setup a route returning `[Int: String]`

lmcd opened this issue · 7 comments

lmcd commented

Describe the issue

Only dictionary responses with String as the key are allowed

Vapor version

4.92.4

Operating system and version

macOS

Swift version

5.9

Steps to reproduce

Setup a route like so:

get("thing") { req -> [Int: String] in
   return [:]
}

Outcome

Observe error:

Referencing instance method 'get(_:use:)' on 'Dictionary' requires the types 'Int' and 'String' be equivalent

Additional notes

No response

This requires CodingKeyRepresentable to solve, which is problematic thanks to it being guarded behind a pointless and unnecessary macOS 12 availability condition.

lmcd commented

Thanks for the quick response.
I'm targeting > macOS 12.3

Edit: seeing same targeting macOS 13.0

Shouldn't we have access to CodingKeyRepresentable now that the minimum version is 5.7?

lmcd commented

Seems to originating here:

extension Dictionary: Content, ResponseEncodable, RequestDecodable, AsyncRequestDecodable, AsyncResponseEncodable where Key == String, Value: Content {
    public static var defaultContentType: HTTPMediaType {
        return .json
    }
}

/// If adding conformance in an extension, you must ensure the type already conforms to `Codable`.

lmcd commented

Could anyone recommend a simple way of overcoming this until it's fixed?

lmcd commented

Ok, I've replace with this, which I know is wrong, but it fixes by use case in the meantime:

extension Dictionary: Content, ResponseEncodable, RequestDecodable, AsyncRequestDecodable, AsyncResponseEncodable where Key: Codable, Value: Content {
    public static var defaultContentType: HTTPMediaType {
        return .json
    }
}

The simple fix would be to define a type that conforms to Content - we can't adopt CodingKey stuff until Vapor 5 so I'm going to close this as there's a workaround