Skip to content

Commit 94ff0a2

Browse files
committed
Refactoring in reference docs
Consolidate the content on `@SchemaMapping` into its own sub-section and make it consistent with the same for `@BatchMapping`. See gh-130
1 parent 429f6f4 commit 94ff0a2

File tree

1 file changed

+121
-119
lines changed

1 file changed

+121
-119
lines changed

spring-graphql-docs/src/docs/asciidoc/index.adoc

Lines changed: 121 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ Spring GraphQL exposes a `BatchLoaderRegistry` that accepts and stores registrat
314314
batch loading functions. The `ExecutionGraphQlService` accepts the registry as input and
315315
uses it to make per request `DataLoader` registrations. A `DataFetcher` then looks up the
316316
`DataLoader` for an entity and uses it to load instances, or in an annotated controller,
317-
simply declare a <<controllers-data-loader,DataLoader argument>> to access the
317+
simply declare a <<controllers-schema-mapping-data-loader,DataLoader argument>> to access the
318318
registered loader. Annotated controllers also support a
319319
<<controllers-batch-mapping,@BatchMapping>> that avoids the need to use `DataLoader`
320320
directly.
@@ -447,8 +447,8 @@ and adds all `RuntimeWiringConfigurer` beans to `GraphQlSource.Builder` and that
447447
support for annotated ``DataFetcher``s, see <<boot-graphql-runtimewiring>>.
448448

449449

450-
[[controllers-mapping]]
451-
=== Mapping
450+
[[controllers-schema-mapping]]
451+
=== `@SchemaMapping`
452452

453453
The `@SchemaMapping` annotation maps a handler method to a field in the GraphQL schema
454454
and declares it to be the `DataFetcher` for that field. The annotation can specify the
@@ -524,148 +524,47 @@ for fields under the Query, Mutation, and Subscription types respectively. For e
524524
}
525525
----
526526

527-
528-
[[controllers-batch-mapping]]
529-
=== Batch Mapping
530-
531-
<<execution-batching>> addresses the N+1 select problem through the use of an
532-
`org.dataloader.DataLoader` to defer the loading of individual entity instances, so they
533-
can be loaded together. For example:
534-
535-
[source,java,indent=0,subs="verbatim,quotes"]
536-
----
537-
@Controller
538-
public class BookController {
539-
540-
public BookController(BatchLoaderRegistry registry) {
541-
registry.forTypePair(Long.class, Author.class).registerMappedBatchLoader((authorIds, env) -> {
542-
// return Map<Long, Author>
543-
});
544-
}
545-
546-
@SchemaMapping
547-
public CompletableFuture<Author> author(Book book, DataLoader<Long, Author> loader) {
548-
return loader.load(book.getAuthorId());
549-
}
550-
551-
}
552-
----
553-
554-
For the straight-forward case of loading an associated entity, shown above, the
555-
`@SchemaMapping` method does nothing more than delegate to the `DataLoader`. This is
556-
boilerplate that can be avoided with a `@BatchMapping` method. For example:
557-
558-
[source,java,indent=0,subs="verbatim,quotes"]
559-
----
560-
@Controller
561-
public class BookController {
562-
563-
@BatchMapping
564-
public Mono<Map<Book, Author>> author(List<Book> books) {
565-
// ...
566-
}
567-
}
568-
----
569-
570-
The above becomes a batch loading function in the `BatchLoaderRegistry`
571-
where keys are `Book` instances and the loaded values their authors. In addition, a
572-
`DataFetcher` is also transparently bound to the `author` field of the type `Book`, which
573-
simply delegates to the `DataLoader` for authors, given its source/parent `Book` instance.
574-
575-
[TIP]
576-
====
577-
To be used as a unique key, `Book` must implement `hashcode` and `equals`.
578-
====
579-
580-
By default, the field name defaults to the method name, while the type name defaults to
581-
the simple class name of the input `List` element type. Both can be customized through
582-
annotation attributes. The type name can also be inherited from a class level
583-
`@SchemaMapping`.
584-
585-
A `@BatchMapping` method can also return a sequence of instances, and that needs to match
586-
the order of the source/parent objects:
587-
588-
[source,java,indent=0,subs="verbatim,quotes"]
589-
----
590-
@Controller
591-
public class BookController {
592-
593-
@BatchMapping
594-
public Flux<Author> author(List<Book> books) {
595-
// ...
596-
}
597-
}
598-
----
599-
600-
It is possible to use imperative method signatures too, i.e. returning `Map<K, V>` or
601-
`List<V>`, which can be useful when there are no remote calls to make.
602-
603-
`BatchMapping` methods support two types of arguments:
604-
605-
[cols="1,2"]
606-
|===
607-
| Method Argument | Description
608-
609-
| `List<K>`
610-
| The source/parent objects.
611-
612-
| `BatchLoaderEnvironment`
613-
| The environment that is available in GraphQL Java to a
614-
`org.dataloader.BatchLoaderWithContext`.
615-
616-
|===
617-
618-
619-
620-
621-
[[controllers-methods]]
622-
=== Handler Methods
623-
624527
`@SchemaMapping` handler methods have flexible signatures and can choose from a range of
625528
method arguments and return values..
626529

627530

628-
[[controllers-arguments]]
629-
==== Method Arguments
531+
[[controllers-schema-mapping-signature]]
532+
==== Method Signature
630533

631-
Annotated handler methods can choose from one of the following method arguments:
534+
Schema mapping handler methods can have any of the following method arguments:
632535

633536
[cols="1,2"]
634537
|===
635538
| Method Argument | Description
636539

637540
| `@Argument`
638541
| For access to field arguments with conversion.
639-
See <<controllers-argument>>.
542+
See <<controllers-schema-mapping-argument>>.
640543

641544
| Source
642545
| For access to the source (i.e. parent/container) instance of the field.
643-
See <<controllers-source>>.
546+
See <<controllers-schema-mapping-source>>.
644547

645548
| `DataLoader`
646549
| For access to a `DataLoader` in the `DataLoaderRegistry`.
647-
See <<controllers-data-loader>>.
550+
See <<controllers-schema-mapping-data-loader>>.
648551

649552
| `GraphQLContext`
650553
| For access to the context from the `DataFetchingEnvironment`.
651-
See <<controllers-graphql-context>>.
554+
See <<controllers-schema-mapping-graphql-context>>.
652555

653556
| `DataFetchingEnvironment`
654557
| For direct access to the underlying `DataFetchingEnvironment`.
655-
See <<controllers-environment>>.
558+
See <<controllers-schema-mapping-environment>>.
656559

657560
|===
658561

562+
Schema mapping handler methods can return any value, including Reactor `Mono` and
563+
`Flux` as described in <<execution-reactive-datafetcher>>.
659564

660-
[[controllers-return-values]]
661-
==== Return Values
662-
663-
Annotated handler methods can return any value, including Reactor `Mono` and `Flux` as
664-
described in <<execution-reactive-datafetcher>>.
665565

666566

667-
668-
[[controllers-argument]]
567+
[[controllers-schema-mapping-argument]]
669568
==== `@Argument`
670569

671570
In GraphQL Java, the `DataFetchingEnvironment` provides access to field-specific argument
@@ -704,7 +603,7 @@ You can use `@Argument` on a `Map<String, Object>` argument, to obtain all argum
704603
values. The name attribute on `@Argument` must not be set.
705604

706605

707-
[[controllers-source]]
606+
[[controllers-schema-mapping-source]]
708607
==== Source
709608

710609
In GraphQL Java, the `DataFetchingEnvironment` provides access to the source (i.e.
@@ -727,8 +626,15 @@ The source method argument also helps to determine the type name for the mapping
727626
If the simple name of the Java class matches the GraphQL type, then there is no need to
728627
explicitly specify the type name in the `@SchemaMapping` annotation.
729628

629+
[TIP]
630+
====
631+
A <<controllers-batch-mapping>> handler method can batch load all authors for a query,
632+
given a list of source/parent books objects.
633+
====
634+
635+
730636

731-
[[controllers-data-loader]]
637+
[[controllers-schema-mapping-data-loader]]
732638
==== `DataLoader`
733639

734640
When you register a batch loading function for an entity, as explained in
@@ -769,21 +675,117 @@ instead.
769675
====
770676

771677

772-
[[controllers-graphql-context]]
678+
[[controllers-schema-mapping-graphql-context]]
773679
==== `GraphQLContext`
774680

775681
To access the `GraphQLContext` from the `DataFetchingEnvironment`, declare a method
776682
parameter of the same type.
777683

778684

779-
[[controllers-environment]]
685+
[[controllers-schema-mapping-environment]]
780686
==== `DataFetchingEnvironment`
781687

782688
To access the `DataFetchingEnvironment` directly, declare a method parameter of the same
783689
type.
784690

785691

786692

693+
[[controllers-batch-mapping]]
694+
=== `@BatchMapping`
695+
696+
<<execution-batching>> addresses the N+1 select problem through the use of an
697+
`org.dataloader.DataLoader` to defer the loading of individual entity instances, so they
698+
can be loaded together. For example:
699+
700+
[source,java,indent=0,subs="verbatim,quotes"]
701+
----
702+
@Controller
703+
public class BookController {
704+
705+
public BookController(BatchLoaderRegistry registry) {
706+
registry.forTypePair(Long.class, Author.class).registerMappedBatchLoader((authorIds, env) -> {
707+
// return Map<Long, Author>
708+
});
709+
}
710+
711+
@SchemaMapping
712+
public CompletableFuture<Author> author(Book book, DataLoader<Long, Author> loader) {
713+
return loader.load(book.getAuthorId());
714+
}
715+
716+
}
717+
----
718+
719+
For the straight-forward case of loading an associated entity, shown above, the
720+
`@SchemaMapping` method does nothing more than delegate to the `DataLoader`. This is
721+
boilerplate that can be avoided with a `@BatchMapping` method. For example:
722+
723+
[source,java,indent=0,subs="verbatim,quotes"]
724+
----
725+
@Controller
726+
public class BookController {
727+
728+
@BatchMapping
729+
public Mono<Map<Book, Author>> author(List<Book> books) {
730+
// ...
731+
}
732+
}
733+
----
734+
735+
The above becomes a batch loading function in the `BatchLoaderRegistry`
736+
where keys are `Book` instances and the loaded values their authors. In addition, a
737+
`DataFetcher` is also transparently bound to the `author` field of the type `Book`, which
738+
simply delegates to the `DataLoader` for authors, given its source/parent `Book` instance.
739+
740+
[TIP]
741+
====
742+
To be used as a unique key, `Book` must implement `hashcode` and `equals`.
743+
====
744+
745+
By default, the field name defaults to the method name, while the type name defaults to
746+
the simple class name of the input `List` element type. Both can be customized through
747+
annotation attributes. The type name can also be inherited from a class level
748+
`@SchemaMapping`.
749+
750+
[[controllers-batch-mapping-signature]]
751+
==== Method Signature
752+
753+
Batch mapping methods support two types of arguments:
754+
755+
[cols="1,2"]
756+
|===
757+
| Method Argument | Description
758+
759+
| `List<K>`
760+
| The source/parent objects.
761+
762+
| `BatchLoaderEnvironment`
763+
| The environment that is available in GraphQL Java to a
764+
`org.dataloader.BatchLoaderWithContext`.
765+
766+
|===
767+
768+
Batch mapping methods can return:
769+
770+
[cols="1,2"]
771+
|===
772+
| Return Type | Description
773+
774+
| `Mono<Map<K,V>>`
775+
| A map with parent objects as keys, and batch loaded objects as values.
776+
777+
| `Flux<V>`
778+
| A sequence of batch loaded objects that must be in the same order as the source/parent
779+
objects passed into the method.
780+
781+
| `Map<K,V>`, `Flux<V>`
782+
| Imperative variants, e.g. without remote calls to make.
783+
784+
|===
785+
786+
787+
788+
787789
[[security]]
788790
== Security
789791

0 commit comments

Comments
 (0)