Directives API Reference¶
This section provides detailed API documentation for GraphQL directives in graphene-django-extras
.
BaseExtraGraphQLDirective¶
Abstract base class for all custom GraphQL directives.
Methods¶
get_args()
(staticmethod)¶
Define the arguments that the directive accepts.
Returns: dict
of GraphQL arguments
Example:
@staticmethod
def get_args():
return {
"format": GraphQLArgument(
GraphQLString,
description="Format string"
)
}
resolve(value, directive, root, info, **kwargs)
(staticmethod)¶
Process the field value with the directive.
Parameters:
- value
(Any
): The field value to transform
- directive
(DirectiveNode
): GraphQL directive AST node
- root
(Any
): Root object
- info
(ResolveInfo
): GraphQL resolve info
- **kwargs
: Additional keyword arguments
Returns: Transformed value
String Directives¶
DefaultGraphQLDirective¶
Provides default values for null or empty strings.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
to |
String! |
Yes | Value to use as default |
Example¶
Base64GraphQLDirective¶
Encode or decode strings using base64.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
op |
String |
No | Operation: "encode" or "decode" |
Example¶
Case Conversion Directives¶
LowercaseGraphQLDirective¶
Convert string to lowercase.
UppercaseGraphQLDirective¶
Convert string to uppercase.
CapitalizeGraphQLDirective¶
Capitalize first character, lowercase the rest.
TitleCaseGraphQLDirective¶
Convert to title case (first letter of each word capitalized).
SwapCaseGraphQLDirective¶
Swap case of all characters.
Example¶
Code Style Directives¶
CamelCaseGraphQLDirective¶
Convert string to camelCase.
SnakeCaseGraphQLDirective¶
Convert string to snake_case.
KebabCaseGraphQLDirective¶
Convert string to kebab-case.
Example¶
query {
field {
displayName @camelCase # "myDisplayName"
apiName @snakeCase # "my_api_name"
urlSlug @kebabCase # "my-url-slug"
}
}
String Manipulation Directives¶
StripGraphQLDirective¶
Remove leading and trailing characters.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
chars |
String |
No | Characters to strip (default: whitespace) |
CenterGraphQLDirective¶
Center string within a specified width.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
width |
Int! |
Yes | Total width of result string |
fillchar |
String |
No | Character to use for padding (default: space) |
ReplaceGraphQLDirective¶
Replace occurrences of a substring.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
old |
String! |
Yes | Substring to replace |
new |
String! |
Yes | Replacement string |
count |
Int |
No | Max number of replacements (-1 for all) |
Example¶
query {
post {
content @strip
title @center(width: 50, fillchar: "=")
text @replace(old: "API", new: "Application Programming Interface")
}
}
Number Directives¶
NumberGraphQLDirective¶
Format numbers using Python format strings.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
as |
String! |
Yes | Python format string |
Example¶
query {
product {
price @number(as: ".2f") # "123.45"
weight @number(as: ".3f") # "12.500"
rating @number(as: ".1%") # "45.2%"
}
}
CurrencyGraphQLDirective¶
Format numbers as currency.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
symbol |
String |
No | Currency symbol (default: "$") |
Example¶
query {
product {
priceUSD @currency # "$123.45"
priceEUR @currency(symbol: "€") # "€123.45"
priceGBP @currency(symbol: "£") # "£123.45"
}
}
Mathematical Directives¶
FloorGraphQLDirective¶
Return the floor of a number.
CeilGraphQLDirective¶
Return the ceiling of a number.
Example¶
Date Directives¶
DateGraphQLDirective¶
Format dates and times using various formats.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
format |
String |
No | Date format string (default: "default") |
Format Options¶
Predefined Formats¶
Format | Description | Example |
---|---|---|
"default" |
Standard format | "01 Dec 2023 14:30:00" |
"iso" |
ISO format | "2023-Dec-01T14:30:00" |
"javascript" |
JS Date format | "Fri Dec 01 2023 14:30:00" |
"time ago" |
Relative time | "2 hours ago" |
"time ago 2d" |
Relative with fallback | "Yesterday" or "Dec 01, 2023" |
Custom Format Tokens¶
Token | Description | Example |
---|---|---|
YYYY |
4-digit year | 2023 |
YY |
2-digit year | 23 |
MMMM |
Full month name | December |
MMM |
Short month name | Dec |
MM |
Month number (padded) | 12 |
DD |
Day of month (padded) | 01 |
dddd |
Full day name | Friday |
ddd |
Short day name | Fri |
HH |
Hour (24h, padded) | 14 |
hh |
Hour (12h, padded) | 02 |
mm |
Minutes (padded) | 30 |
ss |
Seconds (padded) | 45 |
A |
AM/PM | PM |
Example¶
query {
post {
createdAt @date(format: "YYYY-MM-DD") # "2023-12-01"
updatedAt @date(format: "MMMM DD, YYYY") # "December 01, 2023"
publishedAt @date(format: "time ago") # "2 hours ago"
timestamp @date(format: "DD/MM/YY HH:mm A") # "01/12/23 02:30 PM"
}
}
List Directives¶
ShuffleGraphQLDirective¶
Randomly reorder list elements.
Example¶
SampleGraphQLDirective¶
Get a random sample from a list.
Arguments¶
Argument | Type | Required | Description |
---|---|---|---|
size |
Int |
No | Number of items to sample |
Example¶
Middleware Integration¶
ExtraGraphQLDirectiveMiddleware¶
Middleware class that processes directives during query execution.
class ExtraGraphQLDirectiveMiddleware:
def resolve(self, next, root, info, **args):
# Process directives on field resolution
pass
Django Settings¶
GRAPHENE = {
'SCHEMA': 'myapp.schema.schema',
'MIDDLEWARE': [
'graphene_django_extras.ExtraGraphQLDirectiveMiddleware',
],
}
Custom Directives¶
Creating Custom Directives¶
from graphene_django_extras.directives.base import BaseExtraGraphQLDirective
from graphql import GraphQLArgument, GraphQLString, GraphQLInt
class TruncateGraphQLDirective(BaseExtraGraphQLDirective):
"""Truncate string to specified length."""
@staticmethod
def get_args():
return {
"length": GraphQLArgument(
GraphQLInt,
description="Maximum length of string"
),
"suffix": GraphQLArgument(
GraphQLString,
description="Suffix to add when truncated"
)
}
@staticmethod
def resolve(value, directive, root, info, **kwargs):
# Extract arguments
length_arg = next(
(arg for arg in directive.arguments if arg.name.value == "length"),
None
)
suffix_arg = next(
(arg for arg in directive.arguments if arg.name.value == "suffix"),
None
)
length = int(length_arg.value.value) if length_arg else 100
suffix = suffix_arg.value.value if suffix_arg else "..."
# Process value
str_value = str(value)
if len(str_value) <= length:
return str_value
return str_value[:length - len(suffix)] + suffix
Registering Custom Directives¶
import graphene
from graphene_django_extras import all_directives
# Add custom directive to the list
custom_directives = [
*all_directives,
TruncateGraphQLDirective()
]
schema = graphene.Schema(
query=Query,
directives=custom_directives
)
Using Custom Directives¶
Directive Utilities¶
Argument Extraction Helper¶
def get_directive_arg(directive, arg_name, default=None):
"""Extract argument value from directive."""
arg = next(
(arg for arg in directive.arguments if arg.name.value == arg_name),
None
)
return arg.value.value if arg else default
Type Checking Helper¶
def ensure_string(value):
"""Ensure value is a string."""
if isinstance(value, six.string_types):
return value
return str(value) if value is not None else ""
Error Handling¶
Graceful Degradation¶
class SafeDirective(BaseExtraGraphQLDirective):
@staticmethod
def resolve(value, directive, root, info, **kwargs):
try:
# Directive processing logic
return process_value(value)
except Exception as e:
# Log error and return original value
logger.warning(f"Directive processing failed: {e}")
return value
Validation¶
class ValidatedDirective(BaseExtraGraphQLDirective):
@staticmethod
def resolve(value, directive, root, info, **kwargs):
if value is None:
return None
if not isinstance(value, (str, int, float)):
raise ValueError("Directive only accepts string/number values")
return process_value(value)
Performance Considerations¶
Caching Directive Results¶
from django.core.cache import cache
class CachedDirective(BaseExtraGraphQLDirective):
@staticmethod
def resolve(value, directive, root, info, **kwargs):
cache_key = f"directive_{hash(str(value))}"
cached_result = cache.get(cache_key)
if cached_result is not None:
return cached_result
result = expensive_processing(value)
cache.set(cache_key, result, 300) # 5 minutes
return result
Directive Ordering¶
# Directives are processed in the order they appear
query {
field @strip @uppercase @truncate(length: 50)
# 1. Strip whitespace
# 2. Convert to uppercase
# 3. Truncate to 50 characters
}
Best Practices¶
Directive Best Practices
- Handle Null Values: Always check for null/undefined values
- Provide Defaults: Use sensible defaults for optional arguments
- Validate Input: Validate argument types and values
- Error Gracefully: Return original value on processing errors
- Document Arguments: Provide clear descriptions for all arguments
- Consider Performance: Cache expensive operations when possible
- Test Thoroughly: Test with various input types and edge cases
Security Considerations¶
class SecureDirective(BaseExtraGraphQLDirective):
@staticmethod
def resolve(value, directive, root, info, **kwargs):
# Validate permissions
user = info.context.user
if not user.is_authenticated:
return value # Don't process for unauthenticated users
# Sanitize input
safe_value = escape_html(str(value))
return process_value(safe_value)
Testing Directives¶
import pytest
from graphene.test import Client
def test_uppercase_directive():
schema = graphene.Schema(
query=Query,
directives=all_directives
)
client = Client(schema)
query = '''
query {
user {
name @uppercase
}
}
'''
result = client.execute(query)
assert result['data']['user']['name'] == 'JOHN DOE'
This comprehensive API reference covers all directive classes and utilities in graphene-django-extras
, providing developers with the knowledge needed to use and create custom GraphQL directives for their applications.