Skip to content

Replace BiMap with plain maps #861

Open

Description

@oryan-block

graphql.kickstart.tools.util.BiMap is a copy of Guava's BiMap we added when we dropped Guava (661769e). Neither Java nor Kotlin has a bidirectional map, so it stuck around. After #851 it doesn't really pull its weight anymore.

Where it's used:

  • SchemaClassScanner builds a BiMap<TypeDefinition, JavaType> (TypeClassDictionary). SchemaParser reads it both ways: dictionary[definition] for enum classes and dictionary.inverse() for InterfaceTypeResolver and UnionTypeResolver.
  • BiMap#put throwing value already present is the only thing that enforces one class per output type. It shows up as Error creating bimap of type => class, which isn't a very helpful message. It also catches classes found through resolver return types, not just dictionary entries, so a replacement needs an explicit check.
  • SchemaParserDictionary stores a plain map since Let input types share a dictionary class #851. getDictionary() still returns a BiMap for backwards compatibility (graphql-spring-boot calls builder.dictionary(dictionary.getDictionary())), but its inverse() only keeps the first name when several input types share a class.

Proposal:

  1. Internally, use two plain maps plus an explicit duplicate check that throws a SchemaClassScannerError naming the class and the types. No API change.
typeToClass.entries.groupBy({ it.value }, { it.key })
    .filterValues { it.size > 1 }
    .forEach { (clazz, types) -> throw SchemaClassScannerError("...") }
val classToType = typeToClass.entries.associate { (type, clazz) -> clazz to type }
  1. Add a replacement for getDictionary() that returns Map<String, Class<*>> under a new name, and deprecate getDictionary(). Changing the return type in place would break binary compatibility.
  2. Switch graphql-spring-boot to the new method.
  3. Remove BiMap in the next major.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions