Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Enum with int values #366

Closed
karthikraobr opened this issue Oct 2, 2018 · 13 comments · May be fixed by #1347
Closed

Enum with int values #366

karthikraobr opened this issue Oct 2, 2018 · 13 comments · May be fixed by #1347
Labels
binder Related to mapping Go to GraphQL types enhancement New feature or request execution

Comments

@karthikraobr
Copy link
Contributor

karthikraobr commented Oct 2, 2018

Is it possible to generate enum with int values rather than string values? Something that looks like the below code?

type Op int32

const (
	Op_NULL   Op = 0
	Op_CREATE Op = 1
	Op_MODIFY Op = 2
	Op_DELETE Op = 3
)

var Op_name = map[int32]string{
	0: "NULL",
	1: "CREATE",
	2: "MODIFY",
	3: "DELETE",
}
var Op_value = map[string]int32{
	"NULL":   0,
	"CREATE": 1,
	"MODIFY": 2,
	"DELETE": 3,
} 

Minimal graphql.schema and models to reproduce

enum Op {
        Op_NULL 
	Op_CREATE
	Op_MODIFY
	Op_DELETE
}

Generates

type Op string

const (
	OpOpNull   Op = "Op_NULL"
	OpOpCreate Op = "Op_CREATE"
	OpOpModify Op = "Op_MODIFY"
	OpOpDelete Op = "Op_DELETE"
)

func (e Op) IsValid() bool {
	switch e {
	case OpOpNull, OpOpCreate, OpOpModify, OpOpDelete:
		return true
	}
	return false
}

func (e Op) String() string {
	return string(e)
}

func (e *Op) UnmarshalGQL(v interface{}) error {
	str, ok := v.(string)
	if !ok {
		return fmt.Errorf("enums must be strings")
	}

	*e = Op(str)
	if !e.IsValid() {
		return fmt.Errorf("%s is not a valid Op", str)
	}
	return nil
}

func (e Op) MarshalGQL(w io.Writer) {
	fmt.Fprint(w, strconv.Quote(e.String()))
}

Is there any way to generate int values rather than string values for enums? Perhaps a custom resolver?

@JulienBreux
Copy link

Good idea! Like grpc generator ;)

@mathewbyrne mathewbyrne added the enhancement New feature or request label Oct 3, 2018
@lwc
Copy link
Member

lwc commented Oct 4, 2018

This is probably a good use-case for ENUM_VALUE directives - they have something similar in the GraphQL Compatibility Acceptance Tests.

@lwc
Copy link
Member

lwc commented Oct 4, 2018

The other option would be custom mapping - you'd be opting out of model generation, but you could map the enum however you like

@mia0x75
Copy link

mia0x75 commented Feb 20, 2019

This is probably a good use-case for ENUM_VALUE directives - they have something similar in the GraphQL Compatibility Acceptance Tests.

@lwc How the directive function looks like?

func EnumInt(ctx context.Context, obj interface{}, next graphql.Resolver, value int) (res interface{}, err error) {
	return value, nil // Just return the value?
}

@longfellowone
Copy link

Another vote for numeric enums

type ItemStatus int

const (
	Waiting ItemStatus = iota
	Filled
	BackOrdered
	OrderExceeded
	NotOrdered
)

func (s ItemStatus) String() string {
	switch s {
	case Waiting:
		return "Waiting"
	case Filled:
		return "Filled"
	case BackOrdered:
		return "Back Ordered"
	case OrderExceeded:
		return "Order Exceeded"
	case NotOrdered:
		return "Not Ordered"
	default:
		return fmt.Sprintf("%d", int(s))
	}
}

@steebchen
Copy link
Contributor

It would also be great for a simple permission system, so I could check for user.Role >= Employee to allow access to "employees" and all roles above (e.g. admin)

@stale
Copy link

stale bot commented Aug 28, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Aug 28, 2019
@stale stale bot closed this as completed Sep 4, 2019
@karthikraobr
Copy link
Contributor Author

@vektah Could you please reopen this issue. Thanks

@vektah vektah reopened this Oct 30, 2019
@stale stale bot removed the stale label Oct 30, 2019
@oshalygin
Copy link
Contributor

@karthikraobr thanks!
This would be very helpful!

@stale
Copy link

stale bot commented Jan 19, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jan 19, 2020
@steebchen
Copy link
Contributor

No stale

@stale stale bot removed the stale label Jan 19, 2020
@tonyhb
Copy link

tonyhb commented Feb 9, 2020

Right now I'm using this fork of enumer which adds GQLGen support via this PR. It may help people :)

@kim-hetrafi
Copy link

kim-hetrafi commented Feb 8, 2021

Is there any progress on this? I'm guessing the above solution won't be merged cause it's solution that adds hacky code which only provides int enums instead of abstacting type support.

My current work around for people wanting to this (doesnt fully auto-generate)

schema.graphqls

enum AccessLevel {
  USER,
  MODERATOR,
  ADMIN
}

run gqlgen generate

add to YOUR_MODEL_FILE.go

var access_level_map = map[string]int {
    "USER": 0,
    "MODERATOR": 1,
    "ADMIN": 2,
}

func (e AccessLevel) Int () int {
	return access_level_map[e.String()]
}

@lwc lwc added binder Related to mapping Go to GraphQL types execution labels Sep 17, 2021
@frederikhors frederikhors converted this issue into discussion #1898 Feb 4, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
binder Related to mapping Go to GraphQL types enhancement New feature or request execution
Projects
None yet
Development

Successfully merging a pull request may close this issue.