Gqlgen: Enum with int values

Created on 2 Oct 2018  路  12Comments  路  Source: 99designs/gqlgen

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?

enhancement

Most helpful comment

Good idea! Like grpc generator ;)

All 12 comments

Good idea! Like grpc generator ;)

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

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

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?
}

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))
    }
}

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)

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.

@vektah Could you please reopen this issue. Thanks

@karthikraobr thanks!
This would be very helpful!

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.

No stale

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

Was this page helpful?
0 / 5 - 0 ratings