github.com/Kartograf/gqlgen@v0.7.2/docs/content/reference/directives.md (about)

     1  ---
     2  title: Using schema directives to implement permission checks
     3  description: Implementing graphql schema directives in golang for permission checks.  
     4  linkTitle: Schema Directives
     5  menu: { main: { parent: 'reference' } }
     6  ---
     7  
     8  Directives are a bit like annotations in any other language. They give you a way to specify some behaviour without directly binding to the implementation. This can be really useful for cross cutting concerns like permission checks.
     9  
    10  **Note**: The current directives implementation is still fairly limited, and is designed to cover the most common "field middleware" case.
    11  
    12  ## Declare it in the schema
    13  
    14  Directives are declared in your schema, along with all your other types. Lets define a @hasRole directive:
    15  
    16  ```graphql
    17  directive @hasRole(role: Role!) on FIELD_DEFINITION
    18  
    19  enum Role {
    20      ADMIN
    21      USER
    22  }
    23  ```
    24  
    25  When we next run go generate, gqlgen will add this directive to the DirectiveRoot 
    26  ```go
    27  type DirectiveRoot struct {
    28  	HasRole func(ctx context.Context, next graphql.Resolver, role Role) (res interface{}, err error)
    29  }
    30  ```
    31  
    32  
    33  ## Use it in the schema
    34  
    35  We can call this on any field definition now:
    36  ```graphql
    37  type Mutation {
    38  	deleteUser(userID: ID!): Bool @hasRole(role: ADMIN)
    39  }
    40  ```
    41  
    42  ## Implement the directive
    43  
    44  Finally, we need to implement the directive, and pass it in when starting the server:
    45  ```go
    46  package main
    47  
    48  func main() {
    49  	c := Config{ Resolvers: &resolvers{} }
    50  	c.Directives.HasRole = func(ctx context.Context, next graphql.Resolver, role Role) (interface{}, error) {
    51  		if !getCurrentUser(ctx).HasRole(role) {
    52  			// block calling the next resolver
    53  			return nil, fmt.Errorf("Access denied")
    54  		}
    55  		
    56  		// or let it pass through
    57  		return next(ctx)
    58  	}
    59  
    60  	http.Handle("/query", handler.GraphQL(todo.NewExecutableSchema(c), ))
    61  	log.Fatal(http.ListenAndServe(":8081", nil))
    62  }
    63  ```