nerdsupremacist / Graphaello

A Tool for Writing Declarative, Type-Safe and Data-Driven Applications in SwiftUI using GraphQL
https://graphaello.dev
MIT License
492 stars 18 forks source link

Passthrough Custom Scalars? #40

Open AlexaderDNT opened 3 years ago

AlexaderDNT commented 3 years ago

Is it possible to use custom scalars for Graphql? Is it activated in the project

nerdsupremacist commented 3 years ago

Hi! Yes it is supported to some extent. It's not been tested very heavily though. Custom scalars right now are always mapped to String.

If you want to use a custom type for it there's a GraphQLScalar protocol you can use. But make sure to make the Scalar typealias to String. Otherwise it won't work.

Here's for example how it works with URL:

extension URL: GraphQLScalar {
    typealias Scalar = String

    static let placeholder: URL = URL(string: "https://graphaello.dev/assets/logo.png")!

    private struct URLScalarDecodingError: Error {
        let string: String
    }

    init(from string: Scalar) throws {
        guard let url = URL(string: string) else {
            throw URLScalarDecodingError(string: string)
        }
        self = url
    }
}

And in your structs you will have to specify that it's the type that you want:

struct MyStuct {
    @GraphQL(MyAPI.path.to.url)
    var url: URL
}

If you try this out, please let me know how it goes. I would love to improve this feature.

I have considered having some config files (yaml or json) to make this work better, but it felt like a weird addition that didn't fit in with the rest. It would make it easier to enforce that all urls are treated equally, though

AlexaderDNT commented 3 years ago

image Getting this error

nerdsupremacist commented 3 years ago

Alright. So this Scalar is definitely not encoded as a string. Not to worry. I'll come up with something for it ;)

I think the best way to configure this is to include the scalar mappings in the API.json and use the CLI to configure it.

Something like:

# Outputs Scalars and Compatible Swift Types (Checking for Conformance to GraphQLScalar)
graphaello scalars list
# Sets Scalar of Point to always be interpreted as a Coordinate 
graphaello scalars set --api MyApi --graphql Point --swift Coordinate
AlexaderDNT commented 3 years ago

Sounds good :)