Polishing in SchemaMappingInspector
This commit is contained in:
@@ -414,8 +414,8 @@ Spring for GraphQL defines the `SelfDescribingDataFetcher` interface to allow a
|
||||
`DataFetcher` to expose return type information. All Spring `DataFetcher` implementations
|
||||
implement this interface. That includes those for <<controllers>>, and those for
|
||||
<<data.querydsl>> and <<data.querybyexample>> Spring Data repositories. For annotated
|
||||
controllers, the return type is derived from the declared return type on `@SchemaMapping`
|
||||
methods.
|
||||
controllers, the return type is derived from the declared return type on a
|
||||
`@SchemaMapping` method.
|
||||
|
||||
On startup, Spring for GraphQL inspects all schema fields, `DataFetcher` registrations,
|
||||
and the properties of Java objects returned from `DataFetcher` implementations in order
|
||||
@@ -432,18 +432,23 @@ GraphQL schema inspection:
|
||||
<1> List of schema fields and their source types that are not mapped
|
||||
<2> List of schema types that are skipped, as explained next
|
||||
|
||||
There are limits to what schema mappings inspection can do, in particular when there is insufficient Java
|
||||
type information. This is the case if an annotated controller method returns
|
||||
`java.lang.Object` such as for a `union` type, or if a `DataFetcher` does not implement
|
||||
`SelfDescribingDataFetcher`. If a schema type is skipped, its name is listed as such in
|
||||
the report, and a DEBUG message is logged to provide a reason for why it was skipped.
|
||||
There are limits to what schema mappings inspection can do, in particular when there is
|
||||
insufficient Java type information. This is the case if an annotated controller method is
|
||||
declared to return `java.lang.Object`, or if the return type has an unspecified generic
|
||||
parameter such as `List<?>`, or if the `DataFetcher` does not implement
|
||||
`SelfDescribingDataFetcher` and the return type is not even known. In such cases, the
|
||||
Java object type structure remains unknown, and the schema type is listed as skipped in
|
||||
the resulting report. For every skipped type, a DEBUG message is logged to indicate why
|
||||
it was skipped.
|
||||
|
||||
For schema `interface` types, the inspection currently checks only fields declared
|
||||
directly on the interface against properties of the Java return type declared by the
|
||||
`DataFetcher`. Additional fields on concrete implementations are not inspected, as there
|
||||
is insufficient information about what Java types may be returned at runtime. This could
|
||||
be improved in a future release to extend inspection to schema `interface` implementing
|
||||
types to look for a match among subtypes of the declared Java return type.
|
||||
Schema union types are always skipped because there is no way for a controller method to
|
||||
declare such a return type in Java, and the Java type structure is unknown.
|
||||
|
||||
Schema interface types are supported only as far as fields declared directly, which are
|
||||
compared against properties on the Java type declared by a `SelfDescribingDataFetcher`.
|
||||
Additional fields on concrete implementations are not inspected. This could be improved
|
||||
in a future release to also inspect scheam `interface` implementation types and to try
|
||||
to find a match among subtypes of the declared Java return type.
|
||||
|
||||
|
||||
[[execution.graphqlsource.operation-caching]]
|
||||
|
||||
@@ -48,24 +48,30 @@ import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* Provide {@link #inspect(GraphQLSchema, RuntimeWiring)} method that checks if
|
||||
* schema fields are covered by either a {@link DataFetcher} registration, or a
|
||||
* Java object property. Fields that have neither are reported as unmapped in
|
||||
* the output {@link Report}.
|
||||
* Declares an {@link #inspect(GraphQLSchema, RuntimeWiring)} method that checks
|
||||
* if schema fields are covered either by a {@link DataFetcher} registration,
|
||||
* or match a Java object property. Fields that have neither are reported as
|
||||
* "unmapped" in the resulting {@link Report Resport}.
|
||||
*
|
||||
* <p>The inspection depends on {@code DataFetcher}s to expose return type
|
||||
* information by implementing {@link SelfDescribingDataFetcher}. This allows
|
||||
* checking if Java object types have properties that match schema fields.
|
||||
* If a {@code DataFetcher} does not implement this interface, then the Java
|
||||
* object type is not known, and the field type is reported as skipped.
|
||||
* <p>The inspection depends on {@code DataFetcher}s to be
|
||||
* {@link SelfDescribingDataFetcher} to be able to compare schema type and Java
|
||||
* object type structure. If a {@code DataFetcher} does not implement this
|
||||
* interface, then the Java type remains unknown, and the field type is reported
|
||||
* as "skipped".
|
||||
*
|
||||
* <p>The {@link SelfDescribingDataFetcher} for annotated controller methods
|
||||
* exposes the declared return type of the controller method. If the return type
|
||||
* is {@link Object} such as for a union, then the Java object structure is
|
||||
* not known, and the field output type is reported as skipped.
|
||||
* <p>The {@code SelfDescribingDataFetcher} for an annotated controller method
|
||||
* derives type information from the controller method signature. If the declared
|
||||
* return type is {@link Object}, or an unspecified generic parameter such as
|
||||
* {@code List<?>} then the Java type structure remains unknown, and the field
|
||||
* output type is reported as skipped.
|
||||
*
|
||||
* <p>Union types are automatically skipped because there is no way for an
|
||||
* annotated controller method to declare the actual Java types.
|
||||
* <p>Unions are always skipped because there is no way for an annotated
|
||||
* controller method to express that in a return type, and the Java type
|
||||
* structure remains unknown.
|
||||
*
|
||||
* <p>Interfaces are supported only as far as fields declared directly on the
|
||||
* interface, which are compared against properties of the Java type declared
|
||||
* by a {@code SelfDescribingDataFetcher}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -242,9 +248,9 @@ class SchemaMappingInspector {
|
||||
|
||||
|
||||
/**
|
||||
* Container of unmapped fields and skipped types.
|
||||
* @param unmappedFields fields with neither {@link DataFetcher} mapping nor Object property
|
||||
* @param skippedTypes types that could not be verified, e.g. union
|
||||
* The report produced as a result of schema mappings inspection.
|
||||
* @param unmappedFields a map with type names as keys, and unmapped field names as values
|
||||
* @param skippedTypes the names of types skipped by the inspection
|
||||
*/
|
||||
public record Report(MultiValueMap<String, String> unmappedFields, Set<String> skippedTypes) {
|
||||
|
||||
|
||||
@@ -21,19 +21,20 @@ import graphql.schema.DataFetcher;
|
||||
import org.springframework.core.ResolvableType;
|
||||
|
||||
/**
|
||||
* Specialized {@link DataFetcher} that can provide information about itself.
|
||||
* Specialized {@link DataFetcher} that exposes additional details such as
|
||||
* return type information.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public interface SelfDescribingDataFetcher<T> extends DataFetcher<T> {
|
||||
|
||||
/**
|
||||
* The type that the {@link DataFetcher} returns.
|
||||
* <p>This could be a type from a {@code @Controller} method declaration
|
||||
* or the type expected to be returned by the {@link DataFetcher}
|
||||
* possibly backed by a Spring Data repository.
|
||||
* The concrete type of the returned instance might be a subclass.
|
||||
* @return the type of the data returned by the data fetcher.
|
||||
* The return type of this {@link DataFetcher}.
|
||||
* <p>This could be derived from the method signature of an annotated
|
||||
* {@code @Controller} method, the domain type of a {@link DataFetcher}
|
||||
* backed by a Spring Data repository, or other.
|
||||
*/
|
||||
ResolvableType getReturnType();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user