Skip to content

Commit edeb801

Browse files
committed
changed readme
1 parent 94e0ba8 commit edeb801

File tree

1 file changed

+123
-15
lines changed

1 file changed

+123
-15
lines changed

README.md

+123-15
Original file line numberDiff line numberDiff line change
@@ -401,20 +401,94 @@ graphqlAnnotations.registerType(new UUIDTypeFunction())
401401
You can also specify custom type function for any field with `@GraphQLType` annotation.
402402

403403
## Directives
404-
You can wire your fields using directives with annotations.
405-
We allow both defining directives using annotations, and wiring fields.
404+
In GraphQL, you can add directives to your schema. Directive is a way of adding some logic to your schema or changing your schema.
405+
For example, we can create a `@upper` directive, that if we add it to string fields in our schema, they will be transformed to upper cases (its an example, you need to implement it).
406406

407-
### Creating/Defining a ``GraphQLDirective``
408-
In order to create a directive, you first have to create a class that the directive will be created from.
409-
For example:
407+
### Declaring a ``GraphQLDirective``
408+
There are multiple ways to declare a directive in your schema using graphql-java-annotations.
409+
410+
#### Using a Java Annotation (recommended)
411+
This is the most recommended way of creating a directive, because it is very easy to use later in your schema.
412+
In order to declare a directive using a java annotation, you first have to create the java annotation, and annotate it with special annotations.
413+
414+
For example, we wish to create a directive that adds suffix to graphql fields.
415+
416+
```java
417+
@GraphQLName("suffix")
418+
@GraphQLDescription("this directive adds suffix to a string type")
419+
@GraphQLDirectiveDefinition(wiring = SuffixWiring.class)
420+
@DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.INTERFACE})
421+
@Retention(RetentionPolicy.RUNTIME)
422+
@interface Suffix {
423+
@GraphQLName("suffixToAdd")
424+
@GraphQLDescription("the suffix to add to your type")
425+
boolean suffixToAdd() default true;
426+
}
427+
```
428+
429+
- must be annotated with `@GraphQLDirectiveDefinition` and to supply a wiring class to it (will be explained later)
430+
- the name of the directive will be taken from the class name `(Suffix)` or if annotated with `@GraphQLName` - from its value
431+
- the description is taken from the `@GraphQLDescription` annotation
432+
- must be annotated with `@Retention` with a `RUNTIME` policy
433+
- must be annotated with `@DirectiveLocations` in order to specify where we can put this directive on (for example - field definition, interface)
434+
435+
You can see that we also defined a ``sufixToAdd`` argument for the directive. We can also use `@GraphQLName` and `@GraphQLDescription` annotations in there.
436+
437+
In order to define a default value for the argument, use the `default` keyword like in the example.
438+
439+
After you created the class, you will be able to create the ``GraphQLDirective`` object using the following code:
440+
```java
441+
GraphQLDirective directive = graphqlAnnotations.directiveViaAnnotation(Suffix.class);
442+
```
443+
444+
#### Using a method declaration
445+
You can also declare an annotation via a method declaration inside some class.
446+
For example, we will create a class of directive declarations:
410447

411448
```java
449+
class DirectiveDeclarations{
412450
@GraphQLName("upper")
413-
@GraphQLDescription("upper")
451+
@GraphQLDescription("upper directive")
452+
@GraphQLDirectiveDefinition(wiring = UpperWiring.class)
414453
@DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.INTERFACE})
415-
public static class UpperDirective {
416-
private boolean isActive = true;
454+
public void upperDirective(@GraphQLName("isActive") @GraphQLDescription("is active") boolean isActive) {
417455
}
456+
457+
@GraphQLName("suffix")
458+
@GraphQLDescription("suffix directive")
459+
@GraphQLDirectiveDefinition(wiring = SuffixWiring.class)
460+
@DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.INTERFACE})
461+
public void suffixDirective(@GraphQLName("suffix") @GraphQLDescription("the suffix") String suffix) {
462+
}
463+
}
464+
```
465+
466+
- The methods has to be annotated with the `@GraphQLDirectiveDefinition` annotation, and to be supplied with a wiring class
467+
- The methods has to be annotated with the `@DirectiveLocations` annotation
468+
- Can be used: `@GraphQLName` and `@GraphQLDescription` - also inside method parameters (that will be transformed into arguments of the directive)
469+
470+
Notice that method params cannot have default values - so the directive arguments will not have default values.
471+
472+
In order to create the directives, you need to write:
473+
```java
474+
Set<GraphQLDirective> set = graphqlAnnotations.directives(DirectiveDeclarations.class);
475+
```
476+
477+
#### Using a class declaration
478+
479+
Another way is to declare the directive using a class.
480+
481+
For example:
482+
483+
```java
484+
@GraphQLName("upper")
485+
@GraphQLDescription("upper")
486+
@DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.INTERFACE})
487+
@GraphQLDirectiveDefinition(wiring = UpperWiring.class)
488+
public static class UpperDirective {
489+
@GraphQLName("isActive")
490+
private boolean isActive = true;
491+
}
418492
```
419493

420494
The name of the directive will be taken from the ``@GraphQLName`` annotation (if not specified, the name will be the class's name).
@@ -426,13 +500,14 @@ You can also use ``@GraphQLName`` and ``@GraphQLDescription`` annotations on the
426500

427501
After you created the class, you will be able to create the ``GraphQLDirective`` object using the following code:
428502
```java
429-
graphqlAnnotations.directive(UpperDirective.class);
503+
GraphQLDirective directive = graphqlAnnotations.directive(UpperDirective.class);
430504
```
431505

432-
### Wiring with directives
433-
Using directives you will be able to wire fields and more, for example, changing the data fetchers of the fields.
506+
### Wiring with the directives
507+
In order to define the wiring logic (what will be executed on top of the graphql type annotated with the directive) we have to create wiring class.
508+
509+
In order to define a wiring functionality, you have to create a Wiring class matching one of your directives. For example:
434510

435-
In order to define a wiring functionality, you have to create a Wiring class matching one of you directives. For example:
436511
```java
437512
public class UpperWiring implements AnnotationsDirectiveWiring {
438513
@Override
@@ -450,17 +525,50 @@ public class UpperWiring implements AnnotationsDirectiveWiring {
450525
}
451526
```
452527

528+
In this example we wrap the data fetcher of the field in order to make the resolved value upper case.
529+
453530
You can also use the `field.transform` method in order to change some of the field's properties.
454531

455532
This class turns your string field to upper case if the directive argument "isActive" is set to true.
456-
Now, you have to wire the field itself:
533+
534+
Put this class inside the `@GraphQLDirectiveDefinition(wiring = UpperWiring.class)` annotation where you declare your directive (see directive declaration section above).
535+
536+
### Using the directives
537+
538+
There are 2 ways of using the directives in your graphql types.
539+
540+
#### Using the directive java annotation (RECOMMENDED)
541+
This way only works if you declared your directive as a java annotation.
542+
In the example above, we created the `@Suffix` annotation as a directive.
543+
So now we can put it on top of our graphql field.
544+
545+
For example:
546+
457547
```java
458548
@GraphQLField
459-
@GraphQLDirectives(@Directive(name = "upperCase", wiringClass = UpperWiring.class, argumentsValues = {"true"}))
460-
public static String name() {
549+
@Suffix(suffixToAdd = " is cool")
550+
public String name(){
461551
return "yarin";
462552
}
463553
```
554+
555+
Now every time the field will be executed, the suffix " is cool" will be added to it.
556+
You can also use directive on field arguments, interfaces, etc.
557+
558+
#### Using `@GraphQLDirectives` annotation
559+
This way works in the 3 methods of declaring directives, but is less recommended because its more complicated and not so nice.
560+
You can annotate your graphql field with the `@GraphQLDirectives` annotation and supply it with the directives to use and the arguments values you want to supply.
561+
562+
For example:
563+
564+
```java
565+
@GraphQLField
566+
@GraphQLDirectives(@Directive(name = "upperCase", argumentsValues = {"true"}))
567+
public String name() {
568+
return "yarin";
569+
}
570+
```
571+
464572
We now wired the field "name" - so it will turn upper case when calling the field.
465573
The ``Directive`` annotations requires the name of the directive, the wiring class (the ``UpperWiring`` class defined earlier), and the values of the arguments. If an argument has a default value, you don't have to supply a value in the arguments values.
466574

0 commit comments

Comments
 (0)