RepoPilot

How do their APIs compare?

About graphql-java/graphql-java · 2 messages · last activity 9/8/2026

Question

How do their APIs compare?

RepoPilot

Comparing the two projects' public APIs highlights how differently they approach exposing functionality to consumers — one is a query-execution engine API, the other a persistence/mapping API.

graphql-java: execution-centric, builder-heavy API

graphql-java's public surface is organized around executing a GraphQL request and getting a structured result back.

  • ExecutionResult is the core output contract — a simple interface exposing getErrors(), getData(), isDataPresent(), and getExtensions() [src/main/java/graphql/ExecutionResult.java:L18-L57]. It's explicitly designed to let callers distinguish "no data because of an error before execution" from "null data due to a field error," per spec semantics.
  • GraphQLContext is a thread-safe, mutable-but-recommended-immutable key/value bag threaded through execution so DataFetchers can access request-scoped state [src/main/java/graphql/GraphQLContext.java:L1-L45]. It's set via ExecutionInput.getGraphQLContext().
  • Scalars exposes the built-in scalar types (GraphQLInt, GraphQLFloat, GraphQLString, GraphQLBoolean, GraphQLID) as static GraphQLScalarType constants built through a fluent newScalar()...build() pattern [src/main/java/graphql/Scalars.java:L22-L62].
  • QueryTraverser exemplifies the library's heavy use of the builder pattern for configuring complex operations — methods like coercedVariables(...), root(...), and rootParentType(...) all return this for chaining, and null-check inputs via assertNotNull [src/main/java/graphql/analysis/QueryTraverser.java:L285-L324].

Overall, graphql-java's API leans on immutable value types + fluent builders, annotated with @PublicApi to mark supported surface area, and increasingly uses @Nullable/@NullMarked (JSpecify) annotations for null-safety documentation, as seen in GraphQLContext [src/main/java/graphql/GraphQLContext.java:L1-L15].

mybatis-3: annotation-driven, XML-parallel API

mybatis-3's API is split between Java annotations (for annotation-based mappers) and XML configuration parsing, both converging on the same internal model (ResultMapping, Configuration).

  • Annotations like @Select let you declare SQL directly on mapper interface methods, e.g. @Select("SELECT id, name FROM users WHERE id = #{id}") [src/main/java/mybatis/mybatis-3/src/main/java/org/apache/ibatis/annotations/Select.java:L1-L40] (documented with usage examples in the Javadoc itself).
  • @Many is a companion annotation for declaring nested collection mappings in @Results/@Result [src/main/java/org/apache/ibatis/annotations/Many.java:L1-L40].
  • ProviderMethodResolver shows a more reflective/dynamic API style: it resolves an SQL-provider method by matching method name and return type (CharSequence), throwing BuilderException on ambiguous or missing matches [src/main/java/org/apache/ibatis/builder/annotation/ProviderMethodResolver.java:L35-L76].
  • XML-facing APIs like XMLConfigBuilder and XMLMapperBuilder parse <properties>, <environments>, <databaseIdProvider>, and <resultMap> elements into configuration objects, exposing behavior through XML attributes rather than Java method calls [src/main/java/org/apache/ibatis/builder/xml/XMLConfigBuilder.java:L214-L253,L294-L333] [src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java:L334-L373].
  • Internally, ResultMappingConstructorResolver resolves which constructor to use for result mapping by matching argument names/types and rejecting ambiguous matches [src/main/java/org/apache/ibatis/builder/ResultMappingConstructorResolver.java:L200-L279] — this is implementation detail behind the declarative annotation/XML API, not part of the public surface itself.

Want to ask your own question?

Open chat for graphql-java/graphql-java

Public Q&A. Generated by RepoPilot from the actual source of graphql-java/graphql-java. AI answers can be incomplete or stale — verify before relying on them.