github.com/99designs/gqlgen@v0.17.45/docs/content/reference/name-collision.md (about)

     1  ---
     2  title: Handling type naming collisions
     3  description: Examples of logic used to avoid type name collision
     4  linkTitle: Name Collision
     5  menu: { main: { parent: 'reference', weight: 10 }}
     6  ---
     7  
     8  While most generated Golang types must have unique names by virtue of being based on their GraphQL `type` counterpart,
     9  which themselves must be unique, there are a few edge scenarios where conflicts can occur.  This document describes
    10  how those collisions are handled.
    11  
    12  ## Enum Constants
    13  
    14  Enum type generation is a prime example of where naming collisions can occur, as we build the const names per value
    15  as a composite of the Enum name and each individual value.
    16  
    17  ### Example Problem
    18  
    19  Currently, enum types are transposed as such:
    20  
    21  ```graphql
    22  # graphql
    23  
    24  enum MyEnum {
    25    value1
    26    value2
    27    value3
    28    value4
    29  }
    30  ```
    31  
    32  Which will result in the following Golang:
    33  
    34  ```go
    35  // golang
    36  
    37  type MyEnum string
    38  
    39  const (
    40  	MyEnumValue1 MyEnum = "value1"
    41  	MyEnumValue2 MyEnum = "value2"
    42  	MyEnumValue3 MyEnum = "value3"
    43  	MyEnumValue4 MyEnum = "value4"
    44  )
    45  ```
    46  
    47  However, those above enum values are just strings.  What if you encounter a scenario where the following is
    48  necessary:
    49  
    50  ```graphql
    51  # graphql
    52  
    53  enum MyEnum {
    54    value1
    55    value2
    56    value3
    57    value4
    58    Value4
    59    Value_4
    60  }
    61  ```
    62  
    63  The `Value4` and `Value_4` enum values cannot be directly transposed into the same "pretty" naming convention as their
    64  resulting constant names would conflict with the name for `value4`, as so:
    65  
    66  ```go
    67  // golang
    68  
    69  type MyEnum string
    70  
    71  const (
    72  	MyEnumValue1 MyEnum = "value1"
    73  	MyEnumValue2 MyEnum = "value2"
    74  	MyEnumValue3 MyEnum = "value3"
    75  	MyEnumValue4 MyEnum = "value4"
    76  	MyEnumValue4 MyEnum = "Value4"
    77  	MyEnumValue4 MyEnum = "Value_4"
    78  )
    79  ```
    80  
    81  Which immediately leads to compilation errors as we now have three constants with the same name, but different values.
    82  
    83  ### Resolution
    84  
    85  1. Store each name generated as part of a run for later comparison
    86  2. Try to coerce name into `CapitalCase`.  Use if no conflicts.
    87     - This process attempts to break apart identifiers into "words", identified by separating on capital letters,
    88       underscores, hyphens, and spaces.
    89     - Each "word" is capitalized and appended to previous word.
    90  3. If non-composite name, append integer to end of name, starting at 0 and going to `math.MaxInt`
    91  4. If composite name, in reverse order, the pieces of the name have a less opinionated converter applied
    92  5. If all else fails, append integer to end of name, starting at 0 and going to `math.MaxInt`
    93  
    94  The first step to produce a name that does not conflict with an existing name succeeds.
    95  
    96  ## Examples
    97  
    98  ### Example A
    99  GraphQL:
   100  ```graphql
   101  # graphql
   102  
   103  enum MyEnum {
   104    Value
   105    value
   106    TitleValue
   107    title_value
   108  }
   109  ```
   110  Go:
   111  ```go
   112  // golang
   113  
   114  type MyEnum string
   115  
   116  const (
   117  	MyEnumValue MyEnum       = "Value"
   118  	MyEnumvalue MyEnum       = "value"
   119  	MyEnumTitleValue MyEnum  = "TitleValue"
   120  	MyEnumtitle_value MyEnum = "title_value"
   121  )
   122  ```
   123  
   124  ### Example B
   125  GraphQL:
   126  ```graphql
   127  # graphql
   128  
   129  enum MyEnum {
   130    TitleValue
   131    title_value
   132    title_Value
   133    Title_Value
   134  }
   135  ```
   136  Go:
   137  ```go
   138  // golang
   139  
   140  type MyEnum string
   141  
   142  const (
   143  	MyEnumTitleValue MyEnum  = "TitleValue"
   144  	MyEnumtitle_value MyEnum = "title_value"
   145  	MyEnumtitle_Value MyEnum = "title_Value"
   146  	MyEnumTitle_Value MyEnum = "Title_Value"
   147  )
   148  ```
   149  
   150  ### Example C
   151  GraphQL:
   152  ```graphql
   153  # graphql
   154  
   155  enum MyEnum {
   156    value
   157    Value
   158  }
   159  ```
   160  Go:
   161  ```go
   162  // golang
   163  
   164  type MyEnum string
   165  
   166  const (
   167  	MyEnumValue  = "value"
   168  	MyEnumValue0 = "Value"
   169  )
   170  ```
   171  
   172  ## Warning
   173  
   174  Name collision resolution is handled per-name, as they come in.  If you change the order of an enum, you could very
   175  well end up with the same constant resolving to a different value.
   176  
   177  Lets mutate [Example C](#example-c):
   178  
   179  ### Example C - State A
   180  GraphQL:
   181  ```graphql
   182  # graphql
   183  
   184  enum MyEnum {
   185    value
   186    Value
   187  }
   188  ```
   189  Go:
   190  ```go
   191  // golang
   192  
   193  type MyEnum string
   194  
   195  const (
   196  	MyEnumValue  = "value"
   197  	MyEnumValue0 = "Value"
   198  )
   199  ```
   200  
   201  ### Example C - State B
   202  GraphQL:
   203  ```graphql
   204  # graphql
   205  
   206  enum MyEnum {
   207    Value
   208    value
   209  }
   210  ```
   211  Go:
   212  ```go
   213  // golang
   214  
   215  type MyEnum string
   216  
   217  const (
   218  	MyEnumValue  = "Value"
   219  	MyEnumValue0 = "value"
   220  )
   221  ```
   222  
   223  Notice how the constant names are the same, but the value that each applies to has changed.