Skip to content
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

Override type mismatch #82

Closed
jonlundy opened this issue Apr 6, 2018 · 3 comments
Closed

Override type mismatch #82

jonlundy opened this issue Apr 6, 2018 · 3 comments

Comments

@jonlundy
Copy link
Contributor

jonlundy commented Apr 6, 2018

Not really a bug.. but more an annoyance for working with the database/sql Scanner/Valuer interfaces.

I am working with a custom type that is defined in graphql as

type Thing {
  listOfEnums: [FooEnum]!
}
enum FooEnum {
   bin, bar, baz
}

the type generated in go is

type FooEnum string
type Thing struct{
  ListOfEnums: []FooEnum
}

the trouble i am running into is this. The value for ListOfEnums is stored in a database as a string bin,bar,baz

for the Valuer interface i can't use []FooEnum as the type but need to define a list type like:

type ListFooEnum []FooEnum
func (f ListFooEnum) Value() (driver.Value, error) {/* logic to convert the list to a string... */}
func (f *ListFooEnum) Scan(value interface{}) (error) {/* logic to convert the string into struct... */}

Currently how i am working around this is by changing the type on the model file to the []FooEnum when running gqlgen and then changing it back to ListFooEnum after.

I understand i could probably use an intermediary step of scanning to the ListFooEnum and casting to the []FooEnum. I am wondering there would be a possibility of having an annotation in the future to set the generated model value to the List version over the [] version.

:)

@vektah
Copy link
Collaborator

vektah commented Apr 19, 2018

I haven't tested this, but you might be able to define the parent (Thing) yourself with the type you need, and point to it in your typemap.

The other way would be to define a custom scalar type for ListFooEnum, and your schema would become:

scalar CommaList
type Thing struct{
  ListOfEnums: CommaList
}

@mastercactapus
Copy link
Contributor

I've ran into this as well. Certain cases make it really painful when the field names match, but have to be exposed through graphql by a different type.

A couple examples:

  • struct with an ID field that is an int but needs to be a string (for graphql)
  • a field is of type time.Time but it must be exposed to graphql as a string in a certain format
  • a field is of a custom enum type that needs to be "mapped" (e.g. iota), but the parent struct would ideally be used directly

In cases where there is a type mismatch during code generation, it would be helpful if there was an option to behave as though there were no matching field at all (thus resolving the type mismatch with use of a resolver method).

The resolver code would then be "best-effort" where possible to auto-map fields. Anything that can't be done automatically would require a method for the Resolver interface, just like if there was no name match.

I don't feel strongly if that should be the default behavior or not though. I think a case could be made to change it, but to preserve current behavior, maybe via a flag like -ignore-type-mismatch or -skip-type-mismatch could be added. Then that flag could be set in the go:generate line where necessary.


Anyway I'd be happy to take a shot at this if it sounds reasonable.

@mastercactapus
Copy link
Contributor

@jonlundy Now that #133 is merged, you should be able to put your mapping in a resolver for that single field (instead of getting type mismatch).

@vektah vektah closed this as completed Jun 25, 2018
cgxxv pushed a commit to cgxxv/gqlgen that referenced this issue Mar 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants