-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding config options for custom schema type names #242
Changes from 1 commit
d0f0807
5e4dd2b
ff25185
3af853f
be4a2ed
ee0315a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{ | ||
"schemaNamespace" : "MySchema", | ||
"schemaDownload": { | ||
... | ||
}, | ||
"input" : { | ||
... | ||
}, | ||
"output" : { | ||
... | ||
}, | ||
"options" : { | ||
... | ||
"schemaCustomization" : { | ||
"customTypeNames" : { | ||
"InterfaceName": { | ||
"interface": { | ||
"name": "CustomInterfaceName" | ||
} | ||
}, | ||
"ScalarName": { | ||
"customScalar": { | ||
"name": "CustomScalarName" | ||
} | ||
}, | ||
"InputObjectName": { | ||
"inputObject": { | ||
"fields": { | ||
"fieldOne": "CustomFieldOne" | ||
}, | ||
"name": "CustomInputObjectName" | ||
} | ||
}, | ||
"ObjectName": { | ||
"object": { | ||
"name": "CustomObjectName" | ||
} | ||
}, | ||
"UnionName": { | ||
"union": { | ||
"name": "CustomUnionName" | ||
} | ||
}, | ||
"EnumName": { | ||
"enum": { | ||
"name": "CustomEnumName", | ||
"cases": { | ||
"enumCase": "CustomEnumCase" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import Foundation | ||
|
||
struct SchemaCustomization: Codable { | ||
|
||
let customTypeNames: [String: CustomSchemaTypeName] | ||
|
||
// MARK: - Codable | ||
|
||
enum CodingKeys: CodingKey, CaseIterable { | ||
case customTypeNames | ||
} | ||
|
||
public init(from decoder: Decoder) throws { | ||
let values = try decoder.container(keyedBy: CodingKeys.self) | ||
try throwIfContainsUnexpectedKey( | ||
container: values, | ||
type: Self.self, | ||
decoder: decoder | ||
) | ||
|
||
customTypeNames = try values.decode( | ||
[String: CustomSchemaTypeName].self, | ||
forKey: .customTypeNames | ||
) | ||
} | ||
|
||
public func encode(to encoder: Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
|
||
try container.encode(self.customTypeNames, forKey: .customTypeNames) | ||
} | ||
|
||
// MARK: - Enums | ||
|
||
enum CustomSchemaTypeName: Codable { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AnthonyMDev @calvincestari Wanted to get a draft up of what I was thinking here for the new config option. Thinking its best to have it be more verbose and descriptive, adds a little more to the JSON to do the configuration but makes it very clear what you are doing. Technically could probably combine the enum for some types into one generic one but keping them separate gives us flexibility going forward to add more options to them individually like the enums or input objects. Also added a sample of hte config JSON showing what they would look like to decode into this structure (that wont be part of the final commit) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like the user is able to specify a bunch of custom type names with this but where do they specify the old schema type that it's being substituted for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, that's fine. The sample JSON didn't seem to reflect this which was confusing. Do we anticipate that users will need this degree of flexibility for type renaming? i.e.: one type named many different things in different contexts? I'm mostly opposed to this being a configuration option vs. a directive. For a directive I was thinking if it could be a type extension in the operation document:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well it would still only allow you to rename a type once, not multiple different times since the type you are renaming is used as the dictionary key. And yea @AnthonyMDev and I discussed config option vs directive and thought this may be the route to go but we can continue that discussions because the data structure I laid out and the further implementation of it will remain the same either way, just how it gets configured would change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes I see that now, my mistake. I'm really not a fan of the JSON configuration, it's too messy compared to a single directive. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm more inclined towards the JSON configuration option because it keeps a clear separation between what is client-side vs the actual schema. In your That said, I think the JSON config format needs to be cleaned up a bit, as this first pass at is is pretty complex and makes actually configuring these things really frustrating and error prone. I'll be posting my opinions on that format in my review shortly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I agree, having to use the 'old' type name in operations alongside the rename directive is confusing. I think we could probably twist our frontend to allow the 'new' name everywhere but is that more or less desirable. Configuring this via JSON still doesn't resolve the problem of needing to use old types in operations but new types in Swift. It's still just as confusing and the JSON config usually doesn't form part of the project source so it's a buried change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think that is less desirable.
I agree with you that it's still a bit confusing having to use the old names in your GraphQL files and the new names in your Swift files, but I think it at least provides a clear line of delineation. You are still writing GraphQL that is valid against your schema. In all places where you are writing GraphQL, you are using the names provided by your schema. The alternatives would be to either:
This would still be the case with the directives unfortunately. They would just be buried in a schema extension I think it's appropriate for this feature to only affect the generated Swift code. And if it only affects the Swift code, I think it's appropriate to keep it as a config option rather than a schema directive. It's never going to be 100% obvious what's going on when you use these custom names. It's not like field aliases that are local to the operation that declares them. These are sweeping overall changes to your schema. |
||
case object(name: String) | ||
case interface(name: String) | ||
case customScalar(name: String) | ||
case union(name: String) | ||
case `enum`(name: String, cases: [String: String]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we might want to make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree ease of use is important, but I also think in general some extra complexity for more explicit clarity of what is happening can be useful as well, in this case both from the JSON side and especially having the different enum cases on the swift side in case there may be times that information is needed. I think a setup like that is a nice middle ground between just strings as you suggested, and having a directive which would make it very clear what type was being modified. That said, I'm happy to make the suggested changes and focus on ease of use. Also yea the |
||
case inputObject(name: String, fields: [String: String]) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Figured we could name this
SchemaCustomizations
so it could potentially contain more options in the future.