Skip to content

Support additional strongly-typed scalars #375

Open
@groue

Description

@groue

Hello,

I was wondering if OpenAPI or the OpenAPI generator could define new scalar types.

New scalar types help disambiguating scalar values such as integers or strings by making them strongly typed: this is a user id, this is an ISO-8601 date, this is a number of seconds, this is an amount of cents. With strong typing, mixing apples and oranges is impossible.

OpenAPI has something that looks pretty much like this:

components:
  schemas:
    # A custom string scalar:
    URL:
      type: string
    
    PhoneNumber:
      type: object
      properties:
        localized_description:
          type: string
        # Not a string, but a URL:
        url:
          $ref: '#/components/schemas/URL'
      required:
        - localized_description
        - url

But OpenAPI Generator imports them as their raw Swift type. For example:

// Generated
public enum Components {
    public enum Schemas {
        /// - Remark: Generated from `#/components/schemas/URL`.
        public typealias URL = Swift.String
    }
}

Somehow I was expecting Components.Schemas.URL to be generated as a RawRepresentable type, as below. I thought that the definition of #/components/schemas/URL was a sufficient hint for the desire of a custom type:

// My expectation
public enum Components {
    public enum Schemas {
        /// - Remark: Generated from `#/components/schemas/URL`.
        public struct URL: Codable, Hashable, Sendable, RawRepresentable {
            public var rawValue: String

            public init(rawValue: String) {
                self.rawValue = rawValue
            }

            public init(from decoder: Decoder) throws {
                let container = try decoder.singleValueContainer()
                try self.init(rawValue: container.decode(String.self))
            }

            public func encode(to encoder: any Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
    }
}

I understand that OpenAPI supports a lot of features, such as string formats, that can turn a simple feature into a very complex beast.

I also understand that not everybody has a real or strong need for strongly-types scalars. They could annoy some users ("All those raw values 🙄").

My previous experience with strongly-types scalars was the Swift GraphQL library Apollo: Custom Scalars. By default, it imports custom scalars as their raw Swift representation (so the URL above with also be a typealias to Swift.String). But it allows the developer to provide a custom implementation. I was able to replace all those raw String and Int with tagged values, with much happiness.

In the end, I wonder what is the opinion of the library maintainers on such a topic?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions