99designs/gqlgen

Support for Custom Omittable Type

Open

#3,227 opened on Aug 23, 2024

View on GitHub
 (2 comments) (0 reactions) (0 assignees)Go (1,250 forks)auto 404
help wantedproposal

Repository metrics

Stars
 (10,737 stars)
PR merge metrics
 (PR metrics pending)

Description

What happened?

I saw that #2585 addresses the problem with undefined vs null in input types, and it's already a great solution for smaller APIs that need to check if a field was explicitly set as nil or not defined at all.

However, in my project we have a lot of DTOs and use github.com/moznion/go-optional.Option to represent our optional types internally. This allows us to decouple our service methods from the GQL layer.

For smaller projects it would be fine to manually map graphql.Omittable to Option with a generic function like this:

func MapToOption[T any](o graphql.Omittable[T]) optional.Option[T] {
	if o.IsSet() {
		return optional.Some(o.Value())
	}
	return optional.None[T]()
}

However, for larger projects it would be nice to use the Modelgen hooks to replace all the Omittable with Option and a custom unmarshaler/marshaler for that type, but as GQLGen doesn't support this because nil values never hit the unmarshaler, I was wondering if an extension to #2585 would be possible with a custom "Omittable" type, in this case Option?

The simplest way to allow this would be via a mapper, that users can provide in the config for each Omittable type that we want to convert:

omittableTypes:
  *string: mypkg.UnmarshalStringOption

What did you expect?

My proposal above or some other way to convert Omittable to Option. Entirely replacing Omittable with Option would be the most elegant.

Minimal graphql.schema and models to reproduce

input UpdateTodoInput {
  text: String @goField(omittable: true, omittableType: "github.com/moznion/go-optional.Option") # alternative to providing omittable types in the config
}

versions

  • go run github.com/99designs/gqlgen version?
  • go version?

Contributor guide