项目作者: LevelFourAB

项目描述 :
Annotation based binding of GraphQL services for Java
高级语言: Java
项目地址: git://github.com/LevelFourAB/graphql-binding.git
创建时间: 2019-08-25T08:47:21Z
项目社区:https://github.com/LevelFourAB/graphql-binding

开源协议:Apache License 2.0

下载


graphql-binding

Version
Dependencies

This is a Java library for binding types and interfaces into GraphQL services
using annotations for use with graphql-java.

  1. @GraphQLObject
  2. @GraphQLName("Example")
  3. public class ExampleService {
  4. @GraphQLField
  5. public String test() {
  6. return "example";
  7. }
  8. }

Features

  • Code-first approach to creating GraphQL types via annotations
  • Explicit bindings, no bindings of anything unless annotated, manually resolved or a scalar
  • Support for object types, enums, interfaces and input types
  • Mixins for object types, allowing GraphQL types to be extended
  • Conversion of objects into GraphQL types
  • Automatic type discovery using an instance of TypeFinder
  • Integration with Dependency Injection via InstanceFactory

License

This project is licensed under the Apache License 2.0,
see the file LICENSE and NOTICE for details.

Usage via Maven

This library are available from Maven central:

  1. <dependency>
  2. <groupId>se.l4.graphql.binding</groupId>
  3. <artifactId>grapqhl-binding</artifactId>
  4. <version>3.0.0</version>
  5. </dependency>

Creating a GraphQLSchema

The GraphQLSchema for use with other GraphQL Java tooling, such as
graphql-java-servlet is
created via the type GraphQLBinder.

  1. GraphQLSchema schema = GraphQLBinder.newBinder()
  2. .withRoot(new RootObject())
  3. .build();

Setting an instance factory

This library uses an InstanceFactory to resolve non-GraphQL instances, the
default version can create objects with default constructors. Guice integration
is available via an InstanceFactory from commons-guice.

  1. binder.setInstanceFactory(factory);

Automatic discovery of types

Types can be automatically discovered using a TypeFinder instance. If a
TypeFinder is provided it will be queried for types that are annotated with
@GraphQLObject, @GraphQLEnum, @GraphQLInterface and @GraphQLInputObject.
Types annotated with @GraphQLRoot will be created via the current
InstanceFactory and added as root objects.

  1. binder.setTypeFinder(TypeFinder.builder()
  2. .setInstanceFactory(instanceFactory) // if using a custom instance factory
  3. .addPackage("root.package.to.scan")
  4. .build()
  5. )

Defining a GraphQL object

GraphQL object types are created via the @GraphQLObject annotation and
placing @GraphQLField on public fields and methods to make them part of the
object.

  1. @GraphQLObject
  2. public class Pet {
  3. @GraphQLField
  4. public final String name;
  5. public Pet(String name) {
  6. this.name = name;
  7. }
  8. @GraphQLField
  9. public String fieldViaMethod(
  10. @GraphQLName("argumentName") String argument
  11. ) {
  12. return argument;
  13. }
  14. }

If a field can not return null it can be annotated with @GraphQLNonNull
to indicate so in the schema. The same is true for arguments. Some types such
as List can also have annotations placed on their inner type:

  1. @GraphQLField
  2. public List<@GraphQLNonNull String> list() {
  3. ...
  4. }

Defining a GraphQL enum

Enumerations can be defined as regular enums with the annotation @GraphQLEnum.
Both the enum class and individual values in the enum can be annotated with
@GraphQLName and @GraphQLDescription.

  1. @GraphQLEnum
  2. public enum PetType {
  3. DOG,
  4. @GraphQLDescription("This is a cat")
  5. CAT;
  6. }

Query and Mutations via root objects

Root queries and mutations are registered via root objects. These can either
be added via binder.withRoot(instance) or when using type finding by
annotating a type with @GraphQLRoot. Several root objects may exist at the
same time and will all contribute to the initial Query and Mutation types.

  1. public class RootObject {
  2. @GraphQLField
  3. public String test() {
  4. return "Hello World";
  5. }
  6. }
  7. binder.withRoot(new GraphQLRootTest());

The above root type would expose a single field named test:

  1. query {
  2. test
  3. }

Use @GraphQLMutation to define mutations:

  1. public class RootObject {
  2. @GraphQLMutation
  3. public String createThing(
  4. @GraphQLName("input") String name
  5. ) {
  6. ...
  7. }
  8. }

Conversion of objects

This library supports the conversion from a non-GraphQL type into a GraphQL
type. This allows one type to return say a Customer and have it mapped into
a CustomerQueryType:

  1. @GraphQLObject
  2. public class CustomersQueryType {
  3. @GraphQLField
  4. public Customer getById(String id) {
  5. // This method can look up and return an instance of Customer
  6. return ...;
  7. }
  8. }
  9. @GraphQLObject
  10. @GraphQLName("Customer")
  11. public class CustomerQueryType {
  12. private final Customer customer;
  13. @GraphQLFactory
  14. public CustomerQueryType(@GraphQLSource Customer customer) {
  15. this.customer = customer;
  16. }
  17. @GraphQLField
  18. @GraphQLDescription("The identifier of the customer")
  19. public String id() {
  20. return customer.getId();
  21. }
  22. }

Add the type to the binder to allow it to register the conversion:

  1. binder.withType(CustomerQueryType.class);

Mixins

Root objects can be used to extend other object types using mixins. This is
useful if one of your modules want to extend a type defined by another module.
Adding @GraphQLMixinField to a method allows it to extend the type defined
by a parameter annotated with @GraphQLSource:

  1. public class RootObject {
  2. @GraphQLMixinField
  3. public int extendedMethod(
  4. @GraphQLSource GraphQLObject source,
  5. @GraphQLName("argumentName") String argument
  6. ) {
  7. ...
  8. }
  9. }